Ключ осколка MongoDB как (ObjectId, ObjectId, RandomKey). Несбалансированные коллекции

Я пытаюсь разделить коллекцию примерно на 6 миллионов документов. Ниже приведены некоторые подробности о сегментированном кластере.

  1. Mongod версии 2.6.7, два шарда, 40% записи, 60% чтения.

  2. В моей базе данных есть события коллекции с примерно 6 миллионами документов. Обычный документ выглядит так:

    {

          _id         : ObjectId,
          sector_id   : ObjectId,
          subsector_id: ObjectId,
          .
          .
          .
    
          Many event specific fields go here
          .
          . 
          created_at: Date,
          updated_at: Date,
          uid       : 16DigitRandomKey
    

    }

  3. Каждый сектор имеет несколько (1,2, ..100) подсекторов, и каждый подсектор имеет несколько событий. Таких секторов 10 000, подсекторов 30000 и событий 6M. Цифры продолжают расти.

  4. Нормальный запрос чтения включает в себя идентификатор_сектора и идентификатор_подсектора. Каждая операция записи включает в себя идентификатор сектора, идентификатор подсектора, uid (уникальный ключ, сгенерированный случайным образом) и остальные данные.

  5. Я пробовал / рассматривал следующие ключи осколков, и результаты описаны ниже:

    а. _id: hashed -> не обеспечивает изоляцию запросов, причина: _id не передается для чтения запроса.

    б. Sector_id: 1, subsctor_id: 1, uid: 1 -> Странное распределение: несколько секторов со старым ObjectId попадают в сегмент 1, несколько секторов со средним возрастом (ObjectId) секторов хорошо сбалансированы и равномерно распределены между обоими сегментами. Несколько секторов с недавним ObjectId остаются на шарде 0.

    c. subsctor_id: hashed -> результаты были такими же, как и для ключа сегмента b.

    d. subsctor_id: 1, uid: 1 -> то же, что и b.

    е. subsctor_id: hashed, uid: 1 -> не может создать такой индекс

    f. uid: 1 -> записи распределяются, но без изоляции запроса

    В чем может быть причина такого неравномерного распределения? Какой может быть правильный ключ осколка на основе заданных данных.


person Atish    schedule 02.07.2015    source источник


Ответы (1)


Я вижу это как ожидаемое поведение Astro, идентификаторы секторов и subsctorIds относятся к типу ObjectId, который содержит метку времени в качестве первых 4 байтов, которые являются монотонными по своей природе и всегда будут переходить в один и тот же фрагмент (и, следовательно, тот же сегмент), поскольку он не может предоставить случайность, которая также указана вами в пункте (b).

Лучший способ выбрать ключ осколка - это ключ, который имеет бизнес-значение (в отличие от некоторых полей ObjectId) и должен быть смешан с некоторым хешем в качестве суффикса, чтобы обеспечить хорошее случайное сочетание для равного распределения. Если у вас есть имя сектора и имя подсектора, попробуйте и дайте нам знать, работает ли он с этим.

вы можете рассмотреть эту ссылку, чтобы выбрать правильный ключ осколка.

сегмент MongoDB по дате на одном компьютере

-$

person Sachin Shukla    schedule 02.07.2015
comment
единственные поля, рассматриваемые для ключа осколка, уже показаны в образце документа. К сожалению, нет таких полей, как имя сектора и / или имя подсектора, которые могут быть частью запроса или ключа шарда. - person Atish; 02.07.2015
comment
хммм ... иногда полезно перевернуть поле ObjectId, чтобы придать ему случайность и избежать проблемы, как я упоминал выше. почему бы вам не попробовать это. - person Sachin Shukla; 02.07.2015
comment
звучит хорошо, но это говорит о том, что мы должны вносить изменения в каждый вызов get, чтобы передать идентификатор сектора и подсекторид в обратном порядке. - person Atish; 03.07.2015