cassandra - проблемы с приложением для чтения и записи с высокой степенью параллелизма
Я реализую приложение, которое генерирует сотни тысяч строк в 4 потока. Каждый поток открывает отдельное соединение с Кассандрой.
Каждый элемент таблицы имеет уникальный хеш-идентификатор (String), но первичным ключом является uuid.
Процесс сохранения элемента следующий:
1) Элемент создан и его хеш рассчитан. 2) Затем выполняется поиск хэша во второй таблице, которая объединяет хэши в соответствии с uuids элемента. 3) Если найдена пара hash - uuid, выполняется поиск элементов uuid (снова 1-ая таблица), и поскольку элемент должен существовать (поскольку была найдена пара "hash - uuid"), элемент загружается из Кассандра в JPA, и это обновляется впоследствии. Если пара "hash - uuid" не найдена, в соответствующей таблице создается новый элемент, а также сохраняется новая пара "hash - uuid".
Генерация данных состоит из двух этапов. Первый шаг выполняется с пустыми таблицами и генерирует первые наборы данных. Там нет ошибок, потому что на шаге Nr. 3, пара "hash - uuid" не найдена, поэтому никаких обновлений не происходит.
На втором шаге весь алгоритм запускается снова, но уже на заполненных таблицах данных. На этом шаге происходят случайные ошибки при чтении элементов данных по их соответствующим uuids (первичным ключам) - иногда сервер не повторяет полные текстовые данные (правильные строки JSON хранятся в таблице, но неполные строки JSON извлекаются в приложение).
Я полностью уверен, что мой алгоритм верен, потому что один и тот же алгоритм работал с hibernate и mysql, даже с postgresql (но так как мне нужны более быстрые записи, я играю с cassandra).
Я использую MacBook Pro с 16 ГБ ОЗУ, для работы с Кассандрой я использую библиотеку Kundera (поддерживает JPA). Что касается Кассандры, я попробовал версию datastax 2.0.4, а также версию 2.0.7, загруженную непосредственно с сайта Apache. Нет кластера, только один экземпляр работает локально на моей машине, на внешнем SSD-диске. Кундера использует CQL v3.
Кто-нибудь знает, как такое поведение может произойти? Есть ли ошибка в драйвере кассандры datastax или в Кундере? Или я неправильно использую кассандру, и база данных не должна использоваться таким образом? Или есть какие-то настройки, о которых я мог забыть?
Единственное, что я изменил в файле конфигурации cassandra - это все тайм-ауты, потому что я получал слишком много TimeoutExceptions со значениями по умолчанию (тайм-ауты произошли во время поиска по первичному ключу)
1 ответ
Я подозреваю, что ваш код не использует соединения Cassandra потокобезопасным способом: необходимо позаботиться о том, чтобы только один поток мог одновременно получить доступ к соединению. Я не знаю, как Кундера подходит к этому, потому что JPA будет генерировать невероятно неэффективные запросы для Кассандры, и я не рекомендую это. Посмотрите ресурсы моделирования данных здесь и используйте родной Java-драйвер CQL.