LedisDB

Материал из Национальной библиотеки им. Н. Э. Баумана
Последнее изменение этой страницы: 13:14, 1 марта 2019.
LedisDB
Ledisdb.png
Разработчики: SiddonTang
Выпущена: 2016
Состояние разработки: Active
Написана на: Go
Операционная система: UNIX
Платформа: x86-64
Локализация: Английский
Тип ПО: NoSQL
Лицензия: Проприетарное
Веб-сайт ledisdb.com

Ledisdb - это высокопроизводительная база данных NoSQL, похожая на Redis, написанная на Go.Она поддерживает множество структур данных, включая: kv, list, hash, zset, set. [Источник 1].

Обзор

Основные особенности

Основными особенностями LedisDB являются:

  • Богатая структура данных: KV, List, Hash, ZSet, Set.
  • Хранение данных не ограничено оперативной памятью.
  • Поддерживаются различные бэкэнды: LevelDB, goleveldb, RocksDB, RAM.
  • Поддерживает скрипты Lua.
  • Поддерживает срок действия и TTL.
  • Может управляться через Redis-Cli.
  • Легко встроить в собственное приложение Go.
  • Поддержка HTTP API, вывод JSON / BSON / msgpack.
  • Репликация, чтобы гарантировать безопасность данных.
  • Предоставляет инструменты для загрузки, выгрузки и восстановления базы данных.
  • Поддерживает кластер, используйте xcodis
  • Аутентификация (правда, не через http)

Отличия от Redis

LedisDB не является Redis, поэтому можно напрямую использовать некоторые клиенты Redis для LedisDB. Но LedisDB использует для связи протокол Redis, и многие API-интерфейсы такие же, как и в Redis, поэтому возможно легко написать свой собственный клиент LedisDB на основе Redis.

Структура данных

LedisDB не имеет типа данных Strings, кроме KV и Bitmap, любые команды Keys и Strings в Redis влияют только на данные KV, а «битовые» команды влияют на Bitmap.

Del

В Redis del можно удалить все данные типа, такие как String, Hash, List и т.д., но в LedisDB del можно удалить только данные KV. Чтобы удалить данные другого типа, нужно использовать команду «очистки» [Источник 1]. .

  • KV: del,mdel
  • Hash: hclear,hmclear
  • Список: lclear,lmclear
  • Набор: sclear,smclear
  • Zset: zclear,zmclear
  • Bitmap: bclear,bmclear

Expire, Persist и TTL

То же самое что и для Del.

  • KV: expire, persist,ttl
  • Hash: hexpire, hpersist,httl
  • Список: lexpire, lpersist,lttl
  • Набор: sexpire, spersist,sttl
  • Zset: zexpire, zpersist,zttl
  • Bitmap: bexpire, bpersist,bttl

ZSet

ZSet поддерживает только int64, а Redis нет.

Transaction

LedisDB поддерживает ACID транзакцию с использованием LMDB или BoltDB, может быть , позже он будет поддерживать multi, exec, discard. API транзакций:

  • begin
  • commit
  • rollback

Scan

LedisDB предоставляет xscanи xrevscan и т.д. Для итеративного извлечения данных и итеративного обратного просмотра.

  • KV: xscan,xrevscan
  • Hash: hxscan,hxrevscan
  • Список: lxscan,lxrevscan
  • Набор: sxscan,sxrevscan
  • Zset: zxscan,zxrevscan
  • Bitmap: bxscan,bxrevscan

Dump

  • KV: dump
  • Hash: hdump
  • Список: ldump
  • Задавать: sdump
  • ZSet: zdump

LedisDB поддерживает dump сериализацию значения с ключом, формат данных такой же, как у Redis, поэтому вы можете использовать его в Redis и наоборот.

Репликация

Сначала LedisDB использует BinLog (например, MySQL BinLog) для поддержки репликации. Ведомый синхронизирует журналы от Мастера с указанным именем и позицией BinLog. Это просто, но не подходит для некоторых случаев.

Давайте предположим сценарий ниже: A -> B и A -> C, здесь A является ведущим, B и C являются ведомыми. -> означает «копия». Если мастер A вышел из строя, мы должны выбрать B или C в качестве нового мастера. Обычно мы должны выбрать тот, который наиболее актуален из A, но не так просто проверить, какой из них.

MySQL имеет ту же проблему для этого, поэтому в MySQL 5.6 он вводит GTID (Global Transaction ID) для ее решения. GTID очень мощный, но немного сложный, я просто хочу простое и легкое решение.

До GTID Google предоставил решение под названием Global Transaction ID, которое использует монотонно увеличивающийся идентификатор группы для представления уникального события транзакции в BinLog. Хотя это имеет некоторые ограничения для иерархической репликации MySQL, я все еще думаю, что использование целочисленного идентификатора, такого как идентификатор группы, для события журнала просто и подходит для LedisDB.

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

Ключевое слово

  • LogID: монотонно увеличивающееся целое число для журнала
  • FirstLogID: самый старый идентификатор журнала для сервера, все журналы перед этим идентификатором были удалены.
  • LastLogID: новейший идентификатор журнала для сервера.
  • CommitID: последний зарегистрированный журнал для выполнения. Если LastLogID равен 10, а CommitID равен 5, серверу необходимо зафиксировать журналы от 6 до 10, чтобы перехватить текущее состояние.

Синхронизация потока

Для master все изменения записи будут обрабатываться ниже:

  • Записывает изменения на диск, он рассчитывает новый LogID на основе LastLogID [Источник 1]..
  • Отправляет этот журнал подчиненным и ожидает подтверждения от подчиненных устройств или времени ожидания.
  • Поручает выполнить изменения.
  • Обновляет CommitID до LogID.

Для slave: Соединяется с мастером и сообщает ему, какой журнал синхронизировать по LogID, это может иметь следующие случаи:

  • LogID меньше, чем FirstLogID главного устройства, master скажет, что slave журнал был очищен, slave устройство должно сначала выполнить полную синхронизацию с ведущим устройством.
  • Master имеет этот журнал и отправит его на slave.
  • Ведущий не имеет этот журнал (ведомый имеет актуальный с ведущим). Slave будет ждать некоторое время или тайм-аут, чтобы начать новую синхронизацию.
  • После того, как ведомое устройство получит журнал (например, LogID 10), он сохранит этот журнал на диск и заметит поток репликации, чтобы обработать его.
  • Ведомый начнет новую синхронизацию с LogID 11.

Полная синхронизация

Если slave синхронизирует журнал, но master очистил его, master должен начать полную синхронизацию.

  • Master создает снимок с текущим LastLogID и создает дамп в файл.
  • Slave удаляет все старые данные и реплицированные журналы, затем загружает файл дампа и обновляет CommitID с LastLogID в файле дампа.
  • Slave начинает синхронизацию с LogID = CommitID + 1.

ReadOnly

Slave всегда только для чтения, что означает, что любые операции записи будут запрещены, кроме FlushAll и репликации. Для master, если журнал сначала пишет OK, но фиксирует или обновляет ошибку CommitID, он также перейдет в режим только для чтения, пока поток репликации не выполнит этот журнал правильно.

Сильная консенсусная репликация

Что касается потока синхронизации, мы видим, что master будет ждать, пока некоторые slave устройства вернут ACK, сообщая, что он получил журнал, этот механизм реализует строгую согласованную репликацию. Если master вышел из строя, мы можем выбрать slave, у которого есть обновленные данные с master.

Использование

Использование репликации очень просто для LedisDB, только с помощью slaveof команды [Источник 2].

  • Используйте slaveof host portдля включения репликации от мастера на «хост: порт».
  • Используйте slaveof no oneдля остановки репликации и смены подчиненного на ведущий.

Если slave устройство сначала синхронизируется с ведущим устройством A, а затем использует его slaveof для синхронизации с master устройством B, оно будет синхронизировано с LogID = LastLogID + 1. Если вы хотите начать заново с устройства B, вы должны использовать, slaveof host port restart который сначала запустит полную синхронизацию.

Ограничения

  • Multi-Master не поддерживается.
  • Репликация не может хранить журнал меньше текущего LastLogID.
  • Циркулярная репликация не поддерживается.
  • Ведущий и ведомый должны установить use_replicationзначение true, чтобы поддерживать репликацию.

Установка

Установка LedisDB

$ #mkdir $WORKSPACE
$ cd $WORKSPACE
$ #git clone git@github.com:siddontang/ledisdb.git src/github.com/siddontang/ledisdb
$ 
$ cd src/github.com/siddontang/ledisdb
$ 
$  #set build and run environment 
$ source dev.sh
$ 
$ make
$ make test

[Источник 2]

Пример сервера

$ #//set run environment if not
$ 
$ #source dev.sh
$ 
$ ./bin/ledis-server -config=/etc/ledis.conf
$ 
$  #set build and run environment 
$ //another shell
$ 
$ ./bin/ledis-cli -p 6380
$ ledis 127.0.0.1:6380> set a 1
$ OK
$ ledis 127.0.0.1:6380> get a
$ "1"
$ 
$ //use curl
$ curl http://127.0.0.1:11181/SET/hello/world
$ → {"SET":[true,"OK"]}
$ 
$ curl http://127.0.0.1:11181/0/GET/hello?type=json
$ → {"GET":"world"}

Пример пакета

$ import (
$ lediscfg "github.com/siddontang/ledisdb/config"
$  "github.com/siddontang/ledisdb/ledis"
$ )
$ 
$ # Use Ledis's default config
$ 
$ cfg := lediscfg.NewConfigDefault()
$ l, _ := ledis.Open(cfg)
$ db, _ := l.Select(0)
$ 
$ db.Set(key, value)
$ db.Get(key)

Пример репликации

$ ledis-cli -p 6381 
$ 
$ ledis 127.0.0.1:6381> slaveof 127.0.0.1 6380
$ OK

Источники

  1. 1,0 1,1 1,2 LedisDB // GitHub. [2016—2019]. Дата обновления: 10.01.2017. URL: https://github.com/siddontang/ledisdb (дата обращения: 05.02.2019).
  2. 2,0 2,1 LedisDB // LedisDB. [2016—2019]. Дата обновления: 08.01.2017. URL: http://ledisdb.com/ (дата обращения: 05.02.2019).

Ссылки