Скажем, у меня есть приложение, которое считывает пакет данных из KAFKA, оно использует ключи входящих сообщений и делает запрос в HBase (читает текущие данные из HBase для этих ключей), выполняет некоторые вычисления и записывает данные вернуться к HBase для того же набора ключей. Например,
{K1, V1}, {K2, V2}, {K3, V3} (входящие сообщения от KAFKA) -> Мое приложение (Считывает текущее значение K1, K2 и K3 из HBase, использует входящее значение V1 , V2 и V3 выполняют некоторые вычисления и записывают новые значения для K1 (V1 + x), K2 (V2 + y) и K3 (V3 + z) обратно в HBase после завершения обработки.
Теперь, допустим, у меня есть один раздел для темы KAFKA и 1 потребитель. У моего приложения есть один потребительский поток, который обрабатывает данные.
Проблема в том, что, скажем, HBase выходит из строя, и в этот момент мое приложение перестает обрабатывать сообщения, и в KAFKA возникает огромное отставание. Даже если у меня есть возможность увеличить количество разделов и, соответственно, потребителей, я не могу увеличить ни один из них из-за условий RACE в HBase. HBase не поддерживает блокировку на уровне строк, поэтому теперь, если я увеличу количество разделов, один и тот же ключ может перейти к двум разным разделам и, соответственно, двум разным потребителям, которые могут оказаться в состоянии RACE, и тот, кто напишет последний, является победителем. Мне придется подождать, пока все сообщения не будут обработаны, прежде чем я смогу увеличить количество разделов.
Например,
HBase отключается -> Изначально у меня есть один раздел для темы, и есть необработанное сообщение -> {K3, V3} в разделе 0 -> теперь я увеличиваю количество разделов, и сообщение с ключом K3 теперь скажем, в разделе 0 и 1 -> тогда потребитель, потребляющий из раздела 0, и другой потребитель, потребляющий из раздела 1, в конечном итоге будут конкурировать с записью в HBase.
Есть ли решение проблемы? Конечно, блокировка ключа K3 потребителем, обрабатывающим сообщение, не является решением, поскольку мы имеем дело с большими данными.