A_Storage - KV Structure
Использование , Примеры простых операций
Формат ключей
Для того чтобы упростить описание ключей, состоящих из нескольких уровней, была введена поддержка составных ключей в виде json-массива строк. Например, описать год рождения пользователя <user_name> можно следующим образом:
["users", "<user_name>", "birth-date", "year"]
Такими ключами легко манипулировать программно.
Реплики
Сервис поддерживает возможность задавать количество реплик для каждого ключа в отдельности. Для этого в каждом запросе задаются параметры N, R, W, которые ответственны за следующее:
- N - количество реплик у данного ключа.
- R - количество, необходимое для поддтверждения чтения, то есть сколько реплик должны ответить, прежде чем значение будет считаться правильно прочитаным.
- W - количество, необходимое для поддтверждения записи, то есть сколько реплик должны сообщить об успешной записи нового значения.
Операции с Key-Value
Установка значения
Есть возможность установки одного или нескольких значений с помощью одного POST запроса /kv/set.
Важно: если в запросах сразу же читается или пишется несколько значений, то это не гарантирует атомарность. Групповые запросы введены для уменьшения количества обращений к сервису. Если до момента выполнения запроса значение не существовало, то оно будет создано.
Пример установки одного значения:
# set some @async_test async def test_set(self): await session.entry(random_key()).set(random_value()) # set None @async_test async def test_set_none(self): await session.entry(random_key()).set(None) # set and check @async_test async def test_return_set_value(self): key = random_key() value = random_value() await session.entry(key).set(value) assert (await session.get_entry(key)).value == value
# set ["k1","k2","k3"] <= "123" $ curl -X PUT "http://api.acapella.ru:12000/v2/kv/keys/k1:k2:k3?&n=3&r=2&w=2" -H "accept: application/json" -H "content-type: application/json" -d "{ \"foo\": 123, \"bar\": 456}" {"version":"1"}
Если в запросе нет ошибок и он корректно обработан, ответ будет со статусом 200 OK.
Если запрос составлен неправильно, вернётся код ошибки 400 Bad Request.
Установка нескольких значений аналогична ситуации с одним значением:
TODO
Чтение значения
Чтение одного или нескольких значений производится с помощью POST запроса /kv/get.
Чтение по ключу, которому ещё не было присвоено ни одно значение, выдаёт null.
В ответе приходит json-массив значений указанных ключей.
Пример:
# get ["k1", "k2", "k3"] - чтение по одному ключу $ curl -X GET "http://api.acapella.ru:12000/v2/kv/keys/k1:k2:k3?wait-timeout=60&transaction=0&n=3&r=2&w=2" -H "accept: application/json" -H "content-type: application/json" {"version":"0","value":{"foo":123.0,"bar":456.0}} # чтение по нескольким ключам TODO # Аргумент запроса `keys` - это массив ключей, которые будут прочитаны. Значения приходят в ответе в том-же порядке, как и ключи в запросе. # get ["not_exists_key"] - чтение не существующего ключа $ curl -X GET "http://api.acapella.ru:12000/v2/kv/keys/not_exists_key?wait-timeout=60&transaction=0&n=3&r=2&w=2" -H "accept: application/json" -H "content-type: application/json" {"version":"0"}
Если в запросе нет ошибок и он корректно обработан, ответ будет со статусом 200 OK.
Если запрос составлен неправильно, вернётся код ошибки 400 Bad Request.
Удаление значения
Данная операция эквивалентна установке значения в null, для любых других операций нет разницы, было ли значение установлено в null, удалено или ещё не было задано.
Выполняется удаление с помощью POST запроса /kv/delete.
# del ["foo"] - удаление одного ключа TODO # удаление нескольких ключей TODO
Аргумент keys - это массив ключей, которые будут удалены.
Если в запросе нет ошибок и он корректно обработан, ответ будет со статусом 200 OK.
Если запрос составлен неправильно, вернётся код ошибки 400 Bad Request.
CAS без транзакций
Если ваша модель данных работает без транзакций , то допустимы одиночные Cas операции, по одному ключу в каждом
# тут все хорошо key = random_key() value = random_value() await session.entry(key).cas(value) assert (await session.get_entry(key)).value == value # этот код бросит исключение CasError key = random_key() value = random_value() entry = await session.get_entry(key) await entry.cas(value, entry.version + 1)
Транзакциионные операции
Создание транзакции \ commit \ rollback
Работа с транзакией требует от клиента знания идентификатора транзакции и только. Никакие объекты и ресурсы ОС не требуются.
# Библиотека для python явно не работает c иджентификатором транзакции async def test_create_tx(self): async with session.transaction(): pass # но можно работать и в "ручном" режиме в особых случаях # https://github.com/AcapellaSoft/AStorageClient/blob/develop/python/src/acapella/kv/Session.py#L53 # example : tr = await session.transaction_manual() e = await tr.get_entry( ['k1_1','k1_2'] )
$ curl -X POST "http://api.acapella.ru:12000/v2/tx" -H "accept: application/json" -H "content-type: application/json" {"index":"8083882192603548991"}
откат транзакции на python
async with session.transaction() as tx: await tx.rollback()
если транзакцию откатили - значение останется старым
key = random_key() async with session.transaction() as tx: e = await tx.get_entry(key) value = e.value await e.set(random_value()) await tx.rollback() async with session.transaction() as tx: e = await tx.get_entry(key) assert value == e.value
Если случиться ошибка - транзакция откатится автоматически
key = random_key() value = None try: async with session.transaction() as tx: e = await tx.get_entry(key) value = e.value await e.set(random_value()) raise Exception() except Exception: pass async with session.transaction() as tx: e = await tx.get_entry(key) assert value == e.value
транзакции изолированы
key = random_key() value = random_value() async with session.transaction() as tx: await tx.entry(key).set(value) async with session.transaction() as tx: e = await tx.get_entry(key) assert value == e.value
чтение и запись ключа из под транзакции
просто указываем transaction= в параметрах запроса
$ curl -X GET "http://api.acapella.ru:12000/v2/kv/keys/k1/k2/k3?wait-timeout=60&transaction=8083882192603548991&n=3&r=2&w=2" -H "accept: application/json" -H "content-type: application/json" {"version":"0","value":{"foo":123.0,"bar":456.0}}
cas операция из под транзакции
Сas операция блокирует на время транзакции прочитанный ключ и отмечает его новое значение (внутри транзакции) до конца транзакции.
Commit транзакции пройдеттолько если все cas ключи не модифицированы , но соответствуют изначальным версиям (первое обращение в транзакции)
Comments
Comments powered by Disqus