Как вы решаете эту проблему?
Это известная проблема, и, конечно, ни простые метки времени, ни глобальная последовательность, ни наивные методы не помогут.
Использование векторные часы со слабой отметкой времени для перечисления ваших событий и векторным курсором для их чтения. Это гарантирует некоторый стабильный детерминированный порядок c для смешивания событий между агрегатами. Это будет работать, даже если каждый поток имеет разрыв синхронизации часов, что является обычным случаем использования для кластеров базы данных, поскольку идеальная синхронизация меток времени невозможна.
Также это автоматически дает возможность беспрепятственно смешивать события чтения из хранилища событий и шины событий позже, и исключает любые блокировки базы данных между различными агрегатными событиями.
Черновик алгоритма:
1) Определите реальное количество одновременных транзакций в вашей базе данных, например, максимальное количество работников в кластере.
Поскольку каждое событие было записано только в одной транзакции в одном потоке вы можете определить его уникальный идентификатор как кортеж (thread number, thread counter)
, где счетчик потока - это количество транзакций, обработанных в текущем потоке.
Рассчитать слабую временную метку события как MAX(thread timestamp, aggregate timestamp)
, где совокупная временная метка - это временная метка последнее событие для текущего агрегата.
2) Подготовить векторный курсор для чтения событий через границу номера потока. Чтение событий из каждого потока последовательно, пока промежуток времени не превысит допустимое значение. Допустимый слабый промежуток времени - это обмен между производительностью чтения событий и сохранением собственного порядка событий.
Минимальное значение - это разность времени синхронизации потоков кластера, поэтому события поступают в порядке собственного смешанного агрегата. Максимальное значение равно бесконечности, поэтому события будут разбиты по совокупности. При использовании СУБД, такой как postgres, это значение может быть автоматически определено с помощью интеллектуального запроса SQL.
Вы можете увидеть референтную реализацию для PostgreSQL базы данных для сохранения событий и загрузка событий . Производительность сохранения событий составляет около 10000 событий в секунду для кластера 4 ГБ ОЗУ RDS Postgres.