Прежде чем двигаться дальше, подумайте о том, чтобы дать нам звезду GitHub ️. Спасибо!
Другие языки: 简体中文 日本語 한국어
Веб-сайт • Документация • Быстрый старт • Разногласия в сообществе • Форум Dragonfly • Присоединяйтесь к сообществу Dragonfly
Обсуждения на GitHub • Проблемы с GitHub • Внесение вклада • Dragonfly Cloud
Dragonfly — это хранилище данных в памяти, созданное для рабочих нагрузок современных приложений.
Полностью совместимая с API-интерфейсами Redis и Memcached, Dragonfly не требует внесения изменений в код. По сравнению с устаревшими хранилищами данных в памяти Dragonfly обеспечивает в 25 раз большую пропускную способность, более высокую частоту обращений в кэш с меньшей задержкой и может использовать до 80 % меньше ресурсов для рабочей нагрузки того же размера.
Сначала мы сравним Dragonfly с Redis на экземпляре m5.large
, который обычно используется для запуска Redis из-за его однопоточной архитектуры. Программа тестирования запускается из другого экземпляра нагрузочного теста (c5n) в той же зоне доступности с использованием memtier_benchmark -c 20 --test-time 100 -t 4 -d 256 --distinct-client-seed
Dragonfly показывает сопоставимую производительность:
--ratio 1:0
):Редис | ДФ |
---|---|
QPS: 159 тыс., P99.9: 1,16 мс, P99: 0,82 мс | QPS: 173K, P99.9: 1,26 мс, P99: 0,9 мс |
--ratio 0:1
):Редис | ДФ |
---|---|
QPS: 194 тыс., P99.9: 0,8 мс, P99: 0,65 мс | QPS: 191 тыс., P99.9: 0,95 мс, P99: 0,8 мс |
Приведенный выше тест показывает, что алгоритмический уровень внутри DF, который позволяет ему масштабироваться по вертикали, не требует больших затрат при однопоточной работе.
Однако если мы возьмем более сильный экземпляр (m5.xlarge), разрыв между DF и Redis начнет расти. ( memtier_benchmark -c 20 --test-time 100 -t 6 -d 256 --distinct-client-seed
):
--ratio 1:0
):Редис | ДФ |
---|---|
QPS: 190 тыс., P99.9: 2,45 мс, P99: 0,97 мс | QPS: 279 тыс., P99.9: 1,95 мс, P99: 1,48 мс |
--ratio 0:1
):Редис | ДФ |
---|---|
QPS: 220 тыс., P99.9: 0,98 мс, P99: 0,8 мс | QPS: 305 тыс., P99.9: 1,03 мс, P99: 0,87 мс |
Пропускная способность Dragonfly продолжает расти с увеличением размера экземпляра, в то время как однопоточный Redis испытывает узкие места в процессоре и достигает локальных максимумов с точки зрения производительности.
Если мы сравним Dragonfly и Redis на самом сетевом экземпляре c6gn.16xlarge, Dragonfly продемонстрирует 25-кратное увеличение пропускной способности по сравнению с одним процессом Redis, превысив 3,8 млн запросов в секунду.
Показатели задержки 99-го процентиля Dragonfly при максимальной пропускной способности:
оп | r6g | c6gn | c7g |
---|---|---|---|
набор | 0,8 мс | 1 мс | 1 мс |
получать | 0,9 мс | 0,9 мс | 0,8 мс |
сетекс | 0,9 мс | 1,1 мс | 1,3 мс |
Все тесты проводились с использованием memtier_benchmark
(см. ниже) с количеством потоков, настроенным для каждого сервера и типа экземпляра. memtier
запускался на отдельной машине c6gn.16xlarge. Мы установили время истечения 500 для теста SETEX, чтобы гарантировать, что он выживет после окончания теста.
memtier_benchmark --ratio ... -t < threads > -c 30 -n 200000 --distinct-client-seed -d 256
--expiry-range=...
В режиме конвейера --pipeline=30
Dragonfly достигает 10 млн QPS для операций SET и 15 млн QPS для операций GET.
Мы сравнили Dragonfly с Memcached на экземпляре c6gn.16xlarge на AWS.
При сопоставимой задержке пропускная способность Dragonfly превзошла пропускную способность Memcached как при рабочих нагрузках записи, так и при чтении. Dragonfly продемонстрировала лучшую задержку при рабочих нагрузках записи из-за конфликтов на пути записи в Memcached.
Сервер | QPS (тысячи запросов в секунду) | задержка 99% | 99,9% |
---|---|---|---|
Стрекоза | ? 3844 | ? 0,9 мс | ? 2,4 мс |
Мемкеш | 806 | 1,6 мс | 3,2 мс |
Сервер | QPS (тысячи запросов в секунду) | задержка 99% | 99,9% |
---|---|---|---|
Стрекоза | ? 3717 | 1 мс | 2,4 мс |
Мемкеш | 2100 | ? 0,34 мс | ? 0,6 мс |
Memcached показал меньшую задержку в тесте чтения, но также и меньшую пропускную способность.
Чтобы проверить эффективность памяти, мы заполнили Dragonfly и Redis примерно 5 ГБ данных с помощью команды debug populate 5000000 key 1024
, отправили трафик обновления с помощью memtier
и запустили создание снимков с помощью команды bgsave
.
На этом рисунке показано, как каждый сервер вел себя с точки зрения эффективности использования памяти.
Dragonfly на 30 % эффективнее использовал память, чем Redis, в состоянии простоя и не продемонстрировал какого-либо видимого увеличения использования памяти на этапе создания моментальных снимков. На пике использование памяти Redis увеличилось почти в 3 раза по сравнению с Dragonfly.
Стрекоза закончила снимок быстрее, за несколько секунд.
Дополнительную информацию об эффективности использования памяти в Dragonfly см. в нашем документе Dashtable.
Dragonfly поддерживает общие аргументы Redis, где это применимо. Например, вы можете запустить: dragonfly --requirepass=foo --bind localhost
.
В настоящее время Dragonfly поддерживает следующие аргументы, специфичные для Redis:
port
: порт подключения Redis ( default: 6379
).bind
: используйте localhost
, чтобы разрешить только подключения к локальному хосту, или общедоступный IP-адрес, чтобы разрешить подключения к этому IP- адресу (т. е. также и извне). Используйте 0.0.0.0
, чтобы разрешить все IPv4.requirepass
: пароль для аутентификации AUTH ( default: ""
).maxmemory
: Ограничение максимального объема памяти (в удобочитаемых байтах), используемого базой данных ( default: 0
). Значение maxmemory
, равное 0
, означает, что программа автоматически определит максимальное использование памяти.dir
: Dragonfly Docker по умолчанию использует папку /data
для создания снимков, CLI использует ""
. Вы можете использовать опцию -v
Docker, чтобы сопоставить его с папкой вашего хоста.dbfilename
: имя файла для сохранения и загрузки базы данных ( default: dump
).Есть также некоторые аргументы, специфичные для Dragonfly:
memcached_port
: порт для включения API-интерфейса, совместимого с Memcached ( default: disabled
).
keys_output_limit
: максимальное количество возвращаемых ключей в команде keys
( default: 8192
). Обратите внимание, что keys
— опасная команда. Мы усекаем его результат, чтобы избежать увеличения использования памяти при получении слишком большого количества ключей.
dbnum
: Максимальное количество поддерживаемых баз данных для select
.
cache_mode
: см. раздел о новом дизайне кэша ниже.
hz
: частота оценки срока действия ключа ( default: 100
). Более низкая частота использует меньше ресурсов ЦП в режиме ожидания за счет более медленной скорости вытеснения.
snapshot_cron
: выражение расписания Cron для автоматических снимков резервного копирования с использованием стандартного синтаксиса cron с точностью до минут ( default: ""
). Ниже приведены несколько примеров выражений расписания cron. Дополнительную информацию об этом аргументе можно найти в нашей документации.
Выражение расписания Cron | Описание |
---|---|
* * * * * | В каждую минуту |
*/5 * * * * | Каждую 5-ю минуту |
5 */2 * * * | На пятой минуте каждого второго часа |
0 0 * * * | В 00:00 (полночь) каждый день |
0 6 * * 1-5 | В 06:00 (рассвет) с понедельника по пятницу. |
primary_port_http_enabled
: разрешает доступ к консоли HTTP на основном порту TCP, если установлено true
( default: true
).
admin_port
: чтобы включить доступ администратора к консоли на назначенном порту ( default: disabled
). Поддерживает протоколы HTTP и RESP.
admin_bind
: для привязки TCP-соединения консоли администратора к заданному адресу ( default: any
). Поддерживает протоколы HTTP и RESP.
admin_nopass
: чтобы включить открытый доступ администратора к консоли на назначенном порту без необходимости токена аутентификации ( default: false
). Поддерживает протоколы HTTP и RESP.
cluster_mode
: поддерживается режим кластера ( default: ""
). В настоящее время поддерживаются только emulated
.
cluster_announce_ip
: IP-адрес, который команды кластера объявляют клиенту.
announce_port
: порт, который команды кластера объявляют клиенту и мастеру репликации.
./dragonfly-x86_64 --logtostderr --requirepass=youshallnotpass --cache_mode=true -dbnum 1 --bind localhost --port 6379 --maxmemory=12gb --keys_output_limit=12288 --dbfilename dump.rdb
Аргументы также могут быть предоставлены через:
--flagfile <filename>
: в каждой строке файла должен быть указан один флаг со знаками равенства вместо пробелов для флагов значений ключа. Для значений флагов не требуются кавычки.DFLY_x
, где x
— точное имя флага с учетом регистра. Для получения дополнительных опций, таких как управление журналами или поддержка TLS, запустите dragonfly --help
.
В настоящее время Dragonfly поддерживает около 185 команд Redis и все команды Memcached, кроме cas
. Следующей вехой Dragonfly, почти такой же, как API Redis 5, станет стабилизация базовой функциональности и реализация API репликации. Если вам нужна команда, которая еще не реализована, откройте проблему.
Для собственной репликации Dragonfly мы разрабатываем формат распределенного журнала, который будет поддерживать на порядок более высокие скорости.
Вслед за функцией репликации мы продолжим добавлять недостающие команды для API Redis версий 3–6.
Пожалуйста, ознакомьтесь с нашим Справочником команд, чтобы узнать о текущих командах, поддерживаемых Dragonfly.
Dragonfly имеет единый, унифицированный, адаптивный алгоритм кэширования, который прост и эффективен в использовании памяти.
Вы можете включить режим кэширования, передав флаг --cache_mode=true
. Как только этот режим включен, Dragonfly будет удалять предметы, на которые с наименьшей вероятностью можно будет наткнуться в будущем, но только тогда, когда он приближается к maxmemory
.
Срок годности ограничен примерно 8 годами.
Сроки истечения с точностью до миллисекунды (PEXPIRE, PSETEX и т. д.) округляются до ближайшей секунды для сроков, превышающих 2^28ms , что имеет погрешность менее 0,001 % и должно быть приемлемым для больших диапазонов. Если это не подходит для вашего случая использования, свяжитесь с нами или откройте проблему, объясняющую ваш случай.
Более подробную информацию о различиях между сроками истечения срока действия Dragonfly и реализациями Redis см. здесь.
По умолчанию Dragonfly разрешает доступ HTTP через свой основной порт TCP (6379). Правильно, к Dragonfly можно подключиться как по протоколу Redis, так и по протоколу HTTP — сервер распознает протокол автоматически при инициации соединения. Попробуйте сделать это в своем браузере. HTTP-доступ в настоящее время не содержит много информации, но в будущем он будет включать полезную информацию для отладки и управления.
Перейдите по URL-адресу :6379/metrics
, чтобы просмотреть метрики, совместимые с Prometheus.
Экспортированные метрики Prometheus совместимы с информационной панелью Grafana, см. здесь.
Важный! Доступ к консоли HTTP предназначен для доступа в безопасной сети. Если вы открываете TCP-порт Dragonfly извне, мы советуем вам отключить консоль с помощью --http_admin_console=false
или --nohttp_admin_console
.
Dragonfly зародился как эксперимент, чтобы увидеть, как могло бы выглядеть хранилище данных в памяти, если бы оно было спроектировано в 2022 году. Основываясь на уроках, извлеченных из нашего опыта пользователей хранилищ памяти и инженеров, работающих в облачных компаниях, мы знали, что нам нужно сохранить два хранилища данных в памяти. Ключевые свойства Dragonfly: гарантия атомарности для всех операций и низкая задержка (до миллисекунды) при очень высокой пропускной способности.
Нашей первой задачей было как полностью использовать ресурсы ЦП, памяти и ввода-вывода с помощью серверов, которые сегодня доступны в публичных облаках. Чтобы решить эту проблему, мы используем архитектуру без разделяемого доступа, которая позволяет нам разделить пространство ключей хранилища памяти между потоками, чтобы каждый поток мог управлять своим собственным фрагментом словарных данных. Мы называем эти фрагменты «осколками». Библиотека, обеспечивающая управление потоками и вводом-выводом для архитектуры без общего доступа, находится здесь с открытым исходным кодом.
Чтобы обеспечить гарантии атомарности для операций с несколькими ключами, мы используем достижения недавних научных исследований. Мы выбрали статью «VLL: модернизация менеджера блокировок для систем баз данных с основной памятью» для разработки транзакционной структуры для Dragonfly. Выбор архитектуры без разделяемого доступа и VLL позволил нам составлять атомарные многоключевые операции без использования мьютексов или спин-блокировок. стало важной вехой в развитии нашего PoC, и его производительность выделялась среди других коммерческих решений и решений с открытым исходным кодом.
Нашей второй задачей было разработать более эффективные структуры данных для нового магазина. Для достижения этой цели мы создали базовую структуру хеш-таблицы на основе статьи «Dash: масштабируемое хеширование в постоянной памяти». Сама статья посвящена области постоянной памяти и не имеет прямого отношения к хранилищам основной памяти, но все же наиболее применима к нашей проблеме. Проект хеш-таблицы, предложенный в статье, позволил нам сохранить два специальных свойства, присутствующих в словаре Redis: возможность инкрементного хеширования во время роста хранилища данных, возможность перемещаться по словарю при изменениях с использованием операции сканирования без сохранения состояния. В дополнение к этим двум свойствам Dash более эффективно использует процессор и память. Используя дизайн Dash, мы смогли усовершенствовать следующие функции:
После того как мы создали основу для Dragonfly и остались довольны ее производительностью, мы приступили к реализации функций Redis и Memcached. На сегодняшний день мы реализовали около 185 команд Redis (примерно эквивалентных API Redis 5.0) и 13 команд Memcached.
И, наконец,
Наша миссия — создать хорошо спроектированное, сверхбыстрое и экономичное хранилище данных в памяти для облачных рабочих нагрузок, использующее преимущества новейших аппаратных достижений. Мы намерены устранить слабые места текущих решений, сохранив при этом их API-интерфейсы и предложения.