Массовая операция Couchbase Gocb дает частично пустые результаты - PullRequest
0 голосов
/ 28 ноября 2018

В нашем коде go с использованием gocb мы запрашиваем представление, которое возвращает идентификаторы 32k.Затем мы выполняем массовый запрос (см. Код ниже), как описано в блоге CouchBase .Однако мы получаем только частичные результаты.Мы можем видеть, что ruleset, _ := items[i].(*gocb.GetOp).Value.(*RuleSet) возвращает значение только для первых 2048 идентификаторов.Тогда идентификаторы 2049 - 11322 не содержат значения и так далее.Наш результат выглядит так:

Line 1 Key: 12345678901234567890123456789012, Value: map[0.0.0.0/0:map[jsona:valueofjsona]]
...
Line 2018 Key: 12345678901234567890123456712345, Value: map[0.0.0.0/0:map[jsona:valueofjsona]]
Line 2019 Key: 12345678901234567890123456712345, Value: map[]
...
Line 11323 Key: 12345678901234567890123456712347, Value: map[jsonb:valueofjsonb]]

(Вышеуказанные строки упрощены, ключи не соответствуют фактическим данным и не соответствуют значению.)

Огромная часть запрошенных данныхфактически не возвращается:

CB# grep '\[\]' result.out |wc -l
27042
CB# wc -l result.out
31988 rdmp.out

Возвращает ли bucket.do до завершения обработки всех запросов?Мы посмотрели на код API и не смогли найти объяснения.

Есть идеи, как решить эту проблему?

type RuleSet struct {
    Rules map[string]interface{} "json:\"rules,\""
}

func DiffViaBulkQuery() {
  var items []gocb.BulkOp
  var row interface{}
  var cnt int = 0
  bucket := cbase.MyBucket()

// [...]
// add 600k entries to itemsget in a loop like 
// itemsGet = append(itemsGet, &gocb.GetOp{Key: key + "_" + strconv.Itoa(i), Value: &Doc{}})


// Perform the bulk operation to Get all documents
  err = bucket.Do(itemsGet)
  if err != nil {
    fmt.Println("ERRROR PERFORMING BULK GET:", err)
  }

// Print the output
  for i := 0; i < len(itemsGet); i++ {
    fmt.Println(itemsGet[i].(*gocb.GetOp).Key, itemsGet[i].(*gocb.GetOp).Value.(*Doc).Item)
  }

Заранее спасибо, Торстен

1 Ответ

0 голосов
/ 29 ноября 2018

Стоит проверить значение ошибки для каждой выполняемой операции.Вы можете сделать это, выполнив op.Err, например, это будет

    for i := 0; i < len(items); i++ {
    fmt.Println(items[i].(*gocb.GetOp).Key, items[i].(*gocb.GetOp).Value.(*Doc).Item, items[i].(*gocb.GetOp).Err)
}

Я ожидаю, что вы увидите, что вы попадаете на queue overflowed ошибки, которые происходят с диспетчером gocbочередь переполняется, по умолчанию максимальный размер составляет 2048 элементов.Решение обычно состоит в том, чтобы выполнять работу небольшими партиями, чтобы не перегружать gocb.Есть похожая проблема с примером на https://forums.couchbase.com/t/bulk-upsert-data-into-couchbase/17354/2

...