Как эффективно создать упорядоченную последовательность в Spanner? - PullRequest
0 голосов
/ 05 декабря 2018

Google Spanner рекомендует не использовать такие вещи, как отметки времени или последовательные числа в качестве начальной части первичного ключа или индекса, что имеет смысл на основе архитектуры.Однако для моих требований мне нужен какой-то способ обеспечения строгого упорядочивания строк «только для добавления».

Я использую Spanner для моделирования событий (как в источнике событий).Каждое событие будет иметь категорию, идентификатор потока, идентифицирующий последовательность, в которой события должны быть строго упорядочены по отношению друг к другу, и несколько полей полезной нагрузки - с этого момента я буду игнорировать фактическую полезную нагрузку.

Наивноэто будет смоделировано как:

| Category    | STRING       |
| Stream Id   | STRING       |
| Sequence Nr | INT64        |

(с первичным ключом, состоящим из Category, Stream Id, Sequence Nr.) Это обеспечит строгий порядок событий для одного потока.Теперь, когда с некоторыми категориями связано много событий, и у лучших советов Spanner есть разница в старших битах, было бы лучше перевернуть это.Каждый «поток» будет содержать достаточно небольшое количество событий (тысячи, а не миллионов) и будет считываться вместе, чтобы облегчить лучшее распределение данных и обеспечить локальность для событий, принадлежащих одному потоку:

| Stream Id   | STRING       |
| Category    | STRING       |
| Sequence Nr | INT64        |

Однако,поскольку я хотел бы иметь возможность добавлять события, не считывая текущее состояние, чтобы узнать текущий порядковый номер, я бы предпочел использовать временную метку.

| Aggregate Id | STRING      |                         | 
| Category     | STRING      |                         |
| Timestamp    | TIMESTAMP   | allow_commit_timestamp  |

В Spanner встроена временная метка коммитаэто отметит его во время фактической обработки транзакции.Но, наконец, к вопросу:

Можно ли представлять данные, как указано выше, и получать уникальные отметки времени фиксации, даже если я фиксирую несколько событий в одной транзакции?

Если нет, возможно ли обеспечить строгое упорядочение каким-либо другим способом, добавив дополнительные столбцы для обеспечения порядка?

В документации указано, что "значения меток времени коммита не гарантируютсяТранзакции, которые записывают в неперекрывающиеся наборы полей, могут иметь одинаковую метку времени. Транзакции, которые записывают в перекрывающиеся наборы полей, имеют уникальные метки времени. "- но я не совсем понимаю, что представляет собой «наборы полей» в этом контексте.

В документации также говорится, что «отметка времени коммита облегчает создание журнала изменений, поскольку отметки времени могут обеспечить порядок упорядочениязаписи в журнале изменений. "но неясно, какие гарантии существуют вокруг временных меток фиксации, имеющих принудительный порядок, в контексте нескольких одновременно работающих пишущих или нескольких событий, записываемых одновременно.

1 Ответ

0 голосов
/ 05 декабря 2018

Если у вас есть несколько событий в одной и той же транзакции , тогда все они будут иметь одинаковую временную отметку фиксации.

Поле - это ячейка таблицы (одно значение столбца в одной строке).Таким образом, «неперекрывающиеся наборы полей» в этом контексте в основном означают отдельные строки, потому что одно из полей является меткой времени фиксации!

Две независимые транзакции, одна обновляющая строка 'R1' иодна строка обновления 'R2' в одной и той же таблице может теоретически иметь одинаковую метку времени фиксации, поскольку они не перекрываются.

Возможно ли представить данные, как указано выше, и получить уникальную фиксациюметки времени, даже если я зафиксирую несколько событий в одной транзакции?

В приведенном вами примере, где вы используете фиксацию времени в своем первичном ключе, нет, вы не сможете добавить несколько событий вОдна и та же пара stream_id / category в одной транзакции, так как они будут иметь одинаковую временную метку и, следовательно, тот же первичный ключ.

Если нет, то можно ли обеспечить строгий порядок каким-либо другим способом, добавивдополнительные столбцы для обеспечения порядка?

Если вы использовали комбинацию отметки времени фиксации и a sequence_number для каждого кортежа (stream_id, category, timestamp), тогда вы можете сохранить строгий порядок в пределах одной транзакции:

Увеличить порядковый номер, начиная с 0, для каждой пары (stream_id, category) в той же транзакции,Временная метка фиксации обеспечит порядок для разных транзакций, а порядковый номер обеспечит порядок в пределах транзакции ...

...