redis-rdb-cli
Это инструмент, который может анализировать, фильтровать, разделять и объединять данные в формате RDB (Redis Database) для офлайн-анализа памяти. Также он позволяет синхронизировать данные между двумя экземплярами Redis и предоставляет возможность настраивать параметры синхронизации для переноса данных в другие системы.
Особенности:
QQ-группа обсуждения: 479688557
Для связи с автором проекта можно использовать адрес электронной почты: chen.bao.yi@qq.com.
Загрузка:
Доступны бинарные релизы на странице GitHub: https://github.com/leonchen83/redis-rdb-cli/releases.
Зависимости времени выполнения:
Требуется Java версии 1.8 или выше.
Установка:
$ wget https://github.com/leonchen83/redis-rdb-cli/releases/download/${version}/redis-rdb-cli-release.zip
$ unzip redis-rdb-cli-release.zip
$ cd ./redis-rdb-cli/bin
$ ./rct -h
Ручная компиляция и зависимости:
Компиляция и запуск:
$ git clone https://github.com/leonchen83/redis-rdb-cli.git
$ cd redis-rdb-cli
$ mvn clean install -Dmaven.test.skip=true
$ cd target/redis-rdb-cli-release/redis-rdb-cli/bin
$ ./rct -h
Запуск в Docker:
Можно запустить программу в Docker с использованием JVM или без неё.
С использованием JVM:
# run with jvm
$ docker run -it --rm redisrdbcli/redis-rdb-cli:latest
$ rct -V
Без использования JVM:
# run without jvm
$ docker run -it --rm redisrdbcli/redis-rdb-cli:latest-native
$ rct -V
Чтобы собрать native image с GraalVM, выполните следующие шаги:
FROM redisrdbcli/redis-rdb-cli:latest as builder
WORKDIR /redis-rdb-cli
COPY . .
RUN mvn package -DskipTests
FROM openjdk:17-jdk-alpine
WORKDIR /app
COPY --from=builder /redis-rdb-cli/target/redis-rdb-cli-release /app/redis-rdb-cli
CMD ["./redis-rdb-cli/bin/rct", "-V"]
docker build -m 8g -f DockerfileNative -t redisrdbcli:redis-rdb-cli .
docker run -it redisrdbcli:redis-rdb-cli bash
bash-5.1# rct -V
Настройка среды Windows:
Добавьте путь к папке bin в переменную Path.
Использование:
Программа предоставляет множество функций для работы с данными RDB, включая анализ, преобразование и синхронизацию данных.
Примеры использования:
rct -f dump -s /path/to/dump.rdb -o /path/to/dump.aof -r
cat /path/to/dump.aof | /redis/src/redis-cli -p 6379 --pipe
rct -f dump -s /path/to/dump.rdb -o /path/to/dump.aof
rct -f json -s /path/to/dump.rdb -o /path/to/dump.json
rct -f count -s /path/to/dump.rdb -o /path/to/dump.csv
rct -f mem -s /path/to/dump.rdb -o /path/to/dump.mem -l 50
rct -f diff -s /path/to/dump1.rdb -o /path/to/dump1.diff
rct -f diff -s /path/to/dump2.rdb -o /path/to/dump2.diff
diff /path/to/dump1.diff /path/to/dump2.diff
rst -s redis://127.0.0.1:6379 -m redis://127.0.0.1:6380 -r
Эти примеры демонстрируют основные функции программы. Резервное копирование удалённого Redis RDB
$ rdt -b redis://192.168.1.105:6379 -o /path/to/dump.rdb
Резервное копирование удалённого Redis RDB и преобразование исходного DB в целевой DB
$ rdt -b redis://192.168.1.105:6379 -o /path/to/dump.rdb --goal 3
Фильтрация RDB
$ rdt -b /path/to/dump.rdb -o /path/to/filtered-dump.rdb -d 0 -t string
Разделение одного RDB на несколько RDB с помощью nodes.conf
$ rdt -s ./dump.rdb -c ./nodes.conf -o /path/to/folder -d 0
Объединение нескольких RDB в один
$ rdt -m ./dump1.rdb ./dump2.rdb -o ./dump.rdb -t hash
Преобразование файла aof-use-rdb-preamble в формат RDB и AOF
$ rcut -s ./aof-use-rdb-preamble.aof -r ./dump.rdb -a ./appendonly.aof
Другие параметры
Дополнительные настраиваемые параметры можно найти в файле /path/to/redis-rdb-cli/conf/redis-rdb-cli.conf
.
Фильтрация
rct
, rdt
и rmt
поддерживают фильтрацию данных по типу, базе данных и ключу с использованием регулярных выражений (в стиле Java).rst
поддерживает только фильтрацию по базе данных.Например:
$ rct -f dump -s /path/to/dump.rdb -o /path/to/dump.aof -d 0
$ rct -f dump -s /path/to/dump.rdb -o /path/to/dump.aof -t string hash
$ rmt -s /path/to/dump.rdb -m redis://192.168.1.105:6379 -r -d 0 1 -t list
$ rst -s redis://127.0.0.1:6379 -m redis://127.0.0.1:6380 -d 0
Мониторинг сервера Redis
# Шаг 1
# Откройте файл `/path/to/redis-rdb-cli/conf/redis-rdb-cli.conf`
# Измените свойство `metric_gateway` с `none` на `influxdb`
# Шаг 2
$ cd /path/to/redis-rdb-cli/dashboard
$ docker-compose up -d
# Шаг 3
$ rmonitor -s redis://127.0.0.1:6379 -n standalone
$ rmonitor -s redis://127.0.0.1:30001 -n cluster
$ rmonitor -s redis-sentinel://sntnl-usr:sntnl-pwd@127.0.0.1:26379?master=mymaster&authUser=usr&authPassword=pwd -n sentinel
# Шаг 4
# В браузере откройте URL `http://localhost:3000/d/monitor/monitor`, войдите с учётными данными `admin`, `admin` в Grafana для просмотра результатов мониторинга.
rmt
исходный Redis сначала выполняет BGSAVE, создавая снимок RDB. Затем команда rmt
переносит данные снимка на целевой Redis. После завершения переноса команда rmt
успешно завершается и останавливается.rst
не только переносит снимок RDB, но и синхронизирует последующие инкрементные данные с целевым Redis. Поэтому команда rst
не останавливается автоматически. Однако её можно остановить, нажав CTRL+C. Команда rst
поддерживает только фильтрацию по базам данных, более подробную информацию см. в разделе «Ограничения синхронизации».С версии v0.1.9
команда rct -f mem
может отображать результаты в Grafana.
Если вы хотите включить эту функцию, необходимо установить Docker и Docker Compose. Инструкции по установке см. на сайте docker. Затем выполните следующие шаги:
$ cd /path/to/redis-rdb-cli/dashboard
# start
$ docker-compose up -d
# stop
$ docker-compose down
Перейдите в каталог /path/to/redis-rdb-cli/conf/redis-rdb-cli.conf
, измените параметр metric_gateway с none
на influxdb
.
Откройте браузер и перейдите по адресу http://localhost:3000
, чтобы просмотреть результаты команды rct -f mem
.
Если вы развёртываете этот инструмент на нескольких экземплярах, вам необходимо изменить параметр metric_instance и убедиться, что он уникален для каждого экземпляра.
$ cd /path/to/redis-6.0-rc1
$ ./utils/gen-test-certs.sh
$ cd tests/tls
$ openssl pkcs12 -export -CAfile ca.crt -in redis.crt -inkey redis.key -out redis.p12
— Укажите source_keystore_path и target_keystore_path на /path/to/redis-6.0-rc1/tests/tls/redis.p12
.
— Установите source_keystore_pass и target_keystore_pass.
rediss://host:port
для включения SSL в ваших командах, например: rst -s rediss://127.0.0.1:6379 -m rediss://127.0.0.1:30001 -r -d 0
.$ rst -s redis://user:pass@127.0.0.1:6379 -m redis://user:pass@127.0.0.1:6380 -r -d 0
+@all
для обработки команд синхронизации.Команда rmt
использует четыре параметра (redis-rdb-cli.conf) для синхронизации данных с удалённым сервером. Перевод текста:
Наиболее важным параметром является migrate_threads=4
. Это означает, что мы используем следующую модель потоков для синхронизации данных:
| | | +----------+ thread 1 | | |---|+----| Endpoint |-------------------|---| || | +----------+ || ||| || ||---| +----------+ thread 2 || ||+----| Endpoint |-------------------|| || | +----------+ || Source Redis |----| | Target Redis ||---| +----------+ thread 3 || ||+----| Endpoint |-------------------|| || | +----------+ || ||| || ||---| +----------+ thread 4 || || +----| Endpoint |-------------------|| +--------------+ +----------+ +--------------+
| | | +----------+ thread 1 | | |---|+----| Endpoints|-------------------|---| || | +----------+ || ||| || ||---| +----------+ thread 2 || ||+----| Endpoints|-------------------|| || | +----------+ || Source Redis |----| | Redis cluster ||---| +----------+ thread 3 || ||+----| Endpoints|-------------------|| || | +----------+ || ||| || ||---| +----------+ thread 4 || || +----| Endpoints|-------------------|| +--------------+ +----------+ +--------------+
Разница между двумя диаграммами заключается в Endpoint
и Endpoints
. В кластерной синхронизации Endpoints
содержит несколько Endpoint
, каждый из которых связан с master
в кластере, например:
В кластере есть 3 мастера и 3 реплики. Если migrate_threads = 4
, то у нас будет 3 * 4 = 12
соединений с кластером Redis.
Следующие три параметра влияют на синхронную производительность:
migrate_batch_size = 4096
: по умолчанию мы используем pipeline
Redis для синхронизации данных. migrate_batch_size
— это размер пакета pipeline
. Если migrate_batch_size = 1
, то размер pipeline
сводится к обработке одной команды и ожиданию возврата результата команды.migrate_retries = 1
: это означает, что если происходит ошибка соединения через сокет, мы создаём новое соединение через сокет и повторно отправляем одну попытку команд, которые не были отправлены ранее.migrate_flush = yes
: это означает, что после каждой записи команды в сокет мы немедленно вызываем SocketOutputStream.flush()
один раз. Если migrate_flush = no
, мы вызываем SocketOutputStream.flush()
только после записи 64 КБ в сокет. Обратите внимание, что этот параметр влияет на migrate_retries
. migrate_reties
действует только при migrate_flush = yes
.+---------------+ +-------------------+ restore +---------------+ | | | redis dump format |---------------->| | | | |-------------------| restore | | | | convert | redis dump format |---------------->| | | Dump rdb |------------>|-------------------| restore | Targe Redis | | | | redis dump format |---------------->| | | | |-------------------| restore | | | | | redis dump format |---------------->| | +---------------+ +-------------------+ +---------------+
Мы синхронизируем данные с кластером через файл nodes.conf
кластера. Потому что мы не обрабатываем MOVED
и ASK
перенаправления. Поэтому единственное ограничение — кластер в период синхронизации должен быть в стабильном состоянии. Это означает, что кластер должен быть без состояний migrating
, importing
и подобных для слота. И не должно быть переключения мастер-ведомый.
rst
для перемещения данных в кластер, следующие команды не поддерживаются: PUBLISH, SWAPDB, MOVE, FLUSHALL, FLUSHDB, MULTI, EXEC, SCRIPT FLUSH, SCRIPT LOAD, EVAL, EVALSHA
. Следующие команды частично поддерживаются: RPOPLPUSH, SDIFFSTORE, SINTERSTORE, SMOVE, ZINTERSTORE, ZUNIONSTORE, DEL, UNLINK, RENAME, RENAMENX, PFMERGE, PFCOUNT, MSETNX, BRPOPLPUSH, BITOP, MSET, COPY, BLMOVE, LMOVE, ZDIFFSTORE, GEOSEARCHSTORE
. Только ключи, которые содержатся в этих командах, поддерживаются, если они находятся в одном слоте (например, del {user}:1 {user}:2
).ret
позволяет пользователям определять собственные службы синхронизации, например, синхронизировать данные Redis с MySQL или MongoDB.Пользователь следует следующим шагам для реализации службы синхронизации:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.your.company</groupId>
<artifactId>your-sink-service</artifactId>
<version>1.0.0</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>com.moilioncircle</groupId>
<artifactId>redis-rdb-cli-api</artifactId>
<version>1.8.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.moilioncircle</groupId>
<artifactId>redis-replicator</artifactId>
<version>[3.6.4, )</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
<scope>provided</scope>
</dependency>
<!--
<dependency>
other dependencies
</dependency>
-->
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
</plugins>
</build>
</project>
SinkService
:
public class YourSinkService implements SinkService {
@Override
public String sink() {
return "your-sink-service";
}
@Override
public void init(File config) throws IOException {
// 解析你的外部配置文件
}
@Override
public void onEvent(Replicator replicator, Event event) {
// 你的同步业务代码
}
}
# 在工程下的 src/main/resources/META-INF/services/ 目录创建 com.moilioncircle.redis.rdb.cli.api.sink.SinkService 文件
|-src
|____main
| |____resources
| | |____META-INF
| | | |____services
| | | | |____com.moilioncircle.redis.rdb.cli.api.sink.SinkService
# В запросе используется язык Java.
#### Текст запроса в переводе на русский язык:
В файле com.moilioncircle.redis.rdb.cli.api.sink.SinkService добавьте следующее:
your.package.YourSinkService
$ mvn clean install
$ cp ./target/your-sink-service-1.0.0-jar-with-dependencies.jar /path/to/redis-rdb-cli/lib
$ ret -s redis://127.0.0.1:6379 -c config.conf -n your-sink-service
public static void main(String[] args) throws Exception {
Replicator replicator = new RedisReplicator("redis://127.0.0.1:6379");
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
Replicators.closeQuietly(replicator);
}));
replicator.addExceptionListener((rep, tx, e) -> {
throw new RuntimeException(tx.getMessage(), tx);
});
SinkService sink = new YourSinkService();
sink.init(new File("/path/to/your-sink.conf"));
replicator.addEventListener(new AsyncEventListener(sink, replicator, 4, Executors.defaultThreadFactory()));
replicator.open();
}
### Как реализовать сервис форматирования
1. Создайте класс YourFormatterService, который наследуется от AbstractFormatterService
```java
public class YourFormatterService extends AbstractFormatterService {
@Override
public String format() {
return "test";
}
@Override
public Event applyString(Replicator replicator, RedisInputStream in, int version, byte[] key, int type, ContextKeyValuePair context) throws IOException {
byte[] val = new DefaultRdbValueVisitor(replicator).applyString(in, version);
getEscaper().encode(key, getOutputStream());
getEscaper().encode(val, getOutputStream());
getOutputStream().write('\n');
return context;
}
}
2. Используйте Java SPI для регистрации этого класса реализации
```text
# create com.moilioncircle.redis.rdb.cli.api.format.FormatterService file in src/main/resources/META-INF/services/
|-src
|____main
| |____resources
| | |____META-INF
| | | |____services
| | | | |____com.moilioncircle.redis.rdb.cli.api.format.FormatterService
# add following content in com.moilioncircle.redis.rdb.cli.api.format.FormatterService
your.package.YourFormatterService
3. Упаковка и развёртывание
```shell
$ mvn clean install
$ cp ./target/your-service-1.0.0-jar-with-dependencies.jar /path/to/redis-rdb-cli/lib
$ rct -f test -s redis://127.0.0.1:6379 -o ./out.csv -t string -d 0 -e json
## Contributors
* [Baoyi Chen](https://github.com/leonchen83)
* [Jintao Zhang](https://github.com/tao12345666333)
* [Maz Ahmadi](https://github.com/cmdshepard)
* [Anish Karandikar](https://github.com/anishkny)
* [Air](https://github.com/air3ijai)
* [Raghu Nandan B S](https://github.com/raghu-nandan-bs)
* Особая благодарность [Kater Technologies](https://www.kater.com/)
### Коммерческие консультации
`redis-rdb-cli` поддерживает следующие коммерческие консультационные услуги:
* Консультации на месте. 50 000 юаней/день
* Обучение на месте. 50 000 юаней/день
Вы можете напрямую связаться с Чен Бао И, отправив электронное письмо по адресу [chen.bao.yi@gmail.com](mailto:chen.bao.yi@qq.com).
### Поддерживается Нин Вэньцзюнь
27 января 2023 года в этот день моя мама Нин Вэньцзюнь (1953–2023) скончалась. Она была доброй, строгой и щедрой старушкой, хотя её пенсия была небольшой, она каждый год жертвовала одежду и деньги бедным горным районам. Она была главной движущей силой, которая поддерживала меня в написании этого инструмента, и каждый раз, когда я говорил ей, что новая компания использует этот инструмент, она была так же счастлива, как и я, и поощряла меня продолжать поддерживать его, а также всегда поощряла меня участвовать в различных технических мероприятиях по обмену. Хотя я не добился больших успехов, она всегда гордилась мной. Возможно, через много лет имя Нин Вэньцзюня будет забыто, но я надеюсь, что Github снова проведёт мероприятие по резервному копированию данных на Северный полюс, чтобы это имя сохранилось на тысячу лет. Пусть покойный покоится с миром.
### Поддерживается IntelliJ IDEA
[IntelliJ IDEA](https://www.jetbrains.com/?from=redis-rdb-cli) — это интегрированная среда разработки (IDE) на Java для разработки компьютерного программного обеспечения.
Он разработан JetBrains (ранее известной как IntelliJ) и доступен в виде бесплатной версии сообщества с лицензией Apache 2,
а также в проприетарной коммерческой версии. Оба могут быть использованы для коммерческого развития.
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )