Таблица содержания
Redis Replicator — это реализация протокола репликации Redis на Java. Он может в реальном времени анализировать, фильтровать и транслировать события RDB и AOF. Также он может синхронизировать данные Redis с локальным кешем или базой данных.
В тексте упоминается команда Writable Command (например, set, hmset) в Redis и исключается команда Readable Command (например, get, hmget). Поддерживаются версии Redis до 6.2.
1.2. Чат с автором
Присоединяйтесь к чату на https://gitter.im/leonchen83/redis-replicator
1.3. Свяжитесь с автором: chen.bao.yi@gmail.com
2.1. Требования:
— минимальная версия JDK 9+ для компиляции;
— минимальная версия JDK 8+ для выполнения;
— Maven 3.3.1+;
— Redis 2.6–7.0.
2.2. Зависимость Maven:
<dependency>
<groupId>com.moilioncircle</groupId>
<artifactId>redis-replicator</artifactId>
<version>3.8.1</version>
</dependency>
2.3. Установка из исходного кода:
2.4. Выбор версии:
Версия Redis | Версия Redis-Replicator |
---|---|
[2.6, 7.2.x] | [3.8.0,] |
[2.6, 7.0.x] | [3.6.4, 3.7.0] |
[2.6, 7.0.x-RC2] | [3.6.2, 3.6.3] |
[2.6, 7.0.0-RC1] | [3.6.0, 3.6.1] |
[2.6, 6.2.x] | [3.5.2, 3.5.5] |
[2.6, 6.2.0-RC1] | [3.5.0, 3.5.1] |
[2.6, 6.0.x] | [3.4.0, 3.4.4] |
[2.6, 5.0.x] | [2.6.1, 3.3.3] |
[2.6, 4.0.x] | [2.3.0, 2.5.0] |
[2.6, 4.0-RC3] | [2.1.0, 2.2.0] |
[2.6, 3.2.x] | [1.0.18] (не поддерживается) |
3.1. Использование:
Replicator replicator = new RedisReplicator("redis://127.0.0.1:6379");
replicator.addEventListener(new EventListener() {
@Override
public void onEvent(Replicator replicator, Event event) {
if (event instanceof KeyStringValueString) {
KeyStringValueString kv = (KeyStringValueString) event;
System.out.println(new String(kv.getKey()));
System.out.println(new String(kv.getValue()));
} else {
....
}
}
});
replicator.open();
3.2. Резервное копирование удалённого снимка RDB: см. RdbBackupExample.java.
3.3. Резервное копирование удалённых команд: см. CommandBackupExample.java.
3.4. Преобразование RDB в формат дампа: мы можем использовать DumpRdbVisitor для преобразования RDB в формат Redis DUMP.
Replicator r = new RedisReplicator("redis:///path/to/dump.rdb");
r.setRdbVisitor(new DumpRdbVisitor(r));
r.addEventListener(new EventListener() {
@Override
public void onEvent(Replicator replicator, Event event) {
if (!(event instanceof
``` **3.5. Rdb check**
Мы можем использовать SkipRdbVisitor для проверки корректности rdb.
```java
Replicator r = new RedisReplicator("redis:///path/to/dump.rdb");
r.setRdbVisitor(new SkipRdbVisitor(r));
r.open();
3.6. Scan и PSYNC
По умолчанию redis-replicator использует PSYNC, чтобы притвориться ведомым и получать команды. Пример:
Replicator r = new RedisReplicator("redis://127.0.0.1:6379");
r.addEventListener(new EventListener() {
@Override
public void onEvent(Replicator replicator, Event event) {
System.out.println(event);
}
});
r.open();
Однако в некоторых облачных сервисах команда PSYNC запрещена, поэтому мы используем команду Scan вместо команды PSYNC.
Пример:
Replicator r = new RedisReplicator("redis://127.0.0.1:6379?enableScan=yes&scanStep=256");
r.addEventListener(new EventListener() {
@Override
public void onEvent(Replicator replicator, Event event) {
System.out.println(event);
}
});
r.open();
3.7. Другие примеры
См. примеры.
@CommandSpec(command = "APPEND")
public static class YourAppendCommand extends AbstractCommand {
private final String key;
private final String value;
public YourAppendCommand(String key, String value) {
this.key = key;
this.value = value;
}
public String getKey() {
return key;
}
public String getValue() {
return value;
}
}
public class YourAppendParser implements CommandParser<YourAppendCommand> {
@Override
public YourAppendCommand parse(Object[] command) {
return new YourAppendCommand(new String((byte[]) command[1], UTF_8), new String((byte[]) command[2], UTF_8));
}
}
Replicator replicator = new RedisReplicator("redis://127.0.0.1:6379");
replicator.addCommandParser(CommandName.name("APPEND"),new YourAppendParser());
replicator.addEventListener(new EventListener() {
@Override
public void onEvent(Replicator replicator, Event event) {
if(event instanceof YourAppendCommand){
YourAppendCommand appendCommand = (YourAppendCommand)event;
// ваш код здесь
}
}
});
Смотрите CommandExtensionExample.java.
$cd /path/to/redis-4.0-rc2/src/modules
$make
loadmodule /path/to/redis-4.0-rc2/src/modules/hellotype.so
public class HelloTypeModuleParser implements ModuleParser<HelloTypeModule> {
@Override
public HelloTypeModule parse(RedisInputStream in, int version) throws IOException {
DefaultRdbModuleParser parser = new DefaultRdbModuleParser(in);
int elements = parser.loadUnsigned(version).intValue();
long[] ary = new long[elements];
int i = 0;
while (elements-- > 0) {
ary[i++] = parser.loadSigned(version);
}
return new HelloTypeModule(ary);
}
}
``` **Перевод текста на русский язык:**
public class HelloTypeModule implements Module { private final long[] value;
public HelloTypeModule(long[] value) {
this.value = value;
}
public long[] getValue() {
return value;
}
}
### 4.2.4. Написать парсер команд
```java
public class HelloTypeParser implements CommandParser<HelloTypeCommand> {
@Override
public HelloTypeCommand parse(Object[] command) {
String key = new String((byte[]) command[1], Constants.UTF_8);
long value = Long.parseLong(new String((byte[]) command[2], Constants.UTF_8));
return new HelloTypeCommand(key, value);
}
}
@CommandSpec(command = "hellotype.insert")
public class HelloTypeCommand extends AbstractCommand {
private final String key;
private final long value;
public long getValue() {
return value;
}
public String getKey() {
return key;
}
public HelloTypeCommand(String key, long value) {
this.key = key;
this.value = value;
}
}
public static void main(String[] args) throws IOException {
Replicator replicator = new RedisReplicator("redis://127.0.0.1:6379");
replicator.addCommandParser(CommandName.name("hellotype.insert"), new HelloTypeParser());
replicator.addModuleParser("hellotype", 0, new HelloTypeModuleParser());
replicator.addEventListener(new EventListener() {
@Override
public void onEvent(Replicator replicator, Event event) {
if (event instanceof KeyStringValueModule) {
System.out.println(event);
}
if (event instanceof HelloTypeCommand) {
System.out.println(event);
}
}
});
replicator.open();
}
См. ModuleExtensionExample.java
Начиная с версии Redis 5.0+, Redis добавляет новую структуру данных STREAM
. Redis-replicator анализирует STREAM
следующим образом:
Replicator r = new RedisReplicator("redis://127.0.0.1:6379");
r.addEventListener(new EventListener() {
@Override
public void onEvent(Replicator replicator, Event event) {
if (event instanceof KeyStringValueStream) {
KeyStringValueStream kv = (KeyStringValueStream)event;
// ключ
String key = kv.getKey();
// поток
Stream stream = kv.getValueAsStream();
// последний идентификатор потока
stream.getLastId();
// записи
NavigableMap<Stream.ID, Stream.Entry> entries = stream.getEntries();
// необязательно : группа
for (Stream.Group group : stream.getGroups()) {
// группа PEL(список ожидающих записей)
NavigableMap<Stream.ID, Stream.Nack> gpel = group.getPendingEntries();
// потребитель
for (Stream.Consumer consumer : group.getConsumers()) {
// потребитель PEL(список ожидающих записей)
NavigableMap<Stream.ID, Stream.Nack> cpel = consumer.getPendingEntries();
}
}
}
}
});
r.open();
YourRdbVisitor
, который расширяет RdbVisitor
.RdbVisitor
в Replicator
с помощью метода setRdbVisitor
.До redis-replicator-2.4.0 мы создавали RedisReplicator
, как показано ниже:
Replicator replicator = new
``` **RedisReplicator("127.0.0.1", 6379, Configuration.defaultSetting());**
**Replicator replicator = new RedisReplicator(new File("/path/to/dump.rdb", FileType.RDB, Configuration.defaultSetting()));**
**Replicator replicator = new RedisReplicator(new File("/path/to/appendonly.aof", FileType.AOF, Configuration.defaultSetting()));**
**Replicator replicator = new RedisReplicator(new File("/path/to/appendonly.aof", FileType.MIXED, Configuration.defaultSetting())**
После версии redis-replicator-2.4.0 мы ввели новое понятие (Redis URI), которое упрощает процесс создания RedisReplicator.
```java
Replicator replicator = new RedisReplicator("redis://127.0.0.1:6379");
Replicator replicator = new RedisReplicator("redis:///path/to/dump.rdb");
Replicator replicator = new RedisReplicator("redis:///path/to/appendonly.aof");
// пример настройки конфигурации
Replicator replicator = new RedisReplicator("redis://127.0.0.1:6379?authPassword=foobared&readTimeout=10000&ssl=yes");
Replicator replicator = new RedisReplicator("redis:///path/to/dump.rdb?rateLimit=1000000");
Replicator replicator = new RedisReplicator("rediss://user:pass@127.0.0.1:6379?rateLimit=1000000").
# 5. Другие темы
## 5.1. Встроенный анализатор команд
| команды | команды | команды | команды | команды | команды |
| -------- | --------- | ----------- | ------- | -------- | ---------- |
| PING | APPEND | SET | SETEX | MSET | DEL |
| SADD | HMSET | HSET | LSET | EXPIRE | EXPIREAT |
| GETSET | HSETNX | MSETNX | PSETEX | SETNX | SETRANGE |
| HDEL | UNLINK | SREM | LPOP | LPUSH | LPUSHX |
| LRem | RPOP | RPUSH | RPUSHX | ZREM | ZINTERSTORE |
| INCR | DECR | INCRBY | ZINCRBY | PERSIST | SELECT |
FLUSHDB | HINCRBY | FLUSHALL | MOVE | SMOVE | BRPOPLPUSH |
PFCOUNT | PFMERGE | SDIFFSTORE | RENAMENX | PEXPIREAT | SINTERSTORE |
ZADD | BITFIELD | SUNIONSTORE | RESTORE | LINSERT | ZREMRANGEBYLEX |
GEOADD | PEXPIRE | ZUNIONSTORE | EVAL | SCRIPT | ZREMRANGEBYRANK |
PUBLISH | BITOP | SETBIT | SWAPDB | PFADD | ZREMRANGEBYSCORE |
RENAME | MULTI | EXEC | LTRIM | RPOPLPUSH | SORT |
EVALSHA | ZPOPMAX | ZPOPMIN | XACK | XADD | XCLAIM |
XDEL | XGROUP | XTRIM | XSETID | COPY | LMOVE |
BLMOVE | ZDIFFSTORE | GEOSEARCHSTORE | FUNCTION | SPUBLISH | |
## 5.2. EOFException
* Настройте параметры сервера Redis следующим образом. Более подробную информацию см. в [redis.conf](https://raw.githubusercontent.com/antirez/redis/3.0/redis.conf).
```java
client-output-buffer-limit slave 0 0 0
ВНИМАНИЕ: эта настройка может привести к нехватке памяти на сервере Redis в некоторых случаях.
<Logger name="com.moilioncircle" level="debug">
<AppenderRef ref="YourAppender"/>
</Logger>
Configuration.defaultSetting().setVerbose(true);
// redis uri
"redis://127.0.0.1:6379?verbose=yes"
System.setProperty("javax.net.ssl.keyStore", "/path/to/keystore");
System.setProperty("javax.net.ssl.keyStorePassword", "password");
System.setProperty("javax.net.ssl.keyStoreType", "your_type");
System.setProperty("javax.net.ssl.trustStore", "/path/to/truststore");
``` **SslConfiguration.defaultSetting().setSslContextFactory(factory);**
**Replicator replicator = new RedisReplicator("rediss://127.0.0.1:6379", ssl);**
### 5.9.2. Поддержка ACL
```java
Replicator replicator = new RedisReplicator("redis://user:pass@127.0.0.1:6379");
Начиная с версии Redis 7.0, добавлена поддержка функции. Структура функции хранится в файле RDB. Мы можем использовать следующий метод для анализа функции.
Replicator replicator = new RedisReplicator("redis://127.0.0.1:6379");
replicator.addEventListener(new EventListener() {
@Override
public void onEvent(Replicator replicator, Event event) {
if (event instanceof Function) {
Function function = (Function) event;
function.getCode();
// ваш код здесь
}
}
});
replicator.open();
Вы также можете проанализировать функцию до сериализованных данных, чтобы использовать FUNCTION RESTORE для восстановления сериализованных данных в целевой Redis.
Replicator replicator = new RedisReplicator("redis://127.0.0.1:6379");
replicator.setRdbVisitor(new DumpRdbVisitor(replicator));
replicator.addEventListener(new EventListener() {
@Override
public void onEvent(Replicator replicator, Event event) {
if (event instanceof DumpFunction) {
DumpFunction function = (DumpFunction) event;
byte[] serialized = function.getSerialized();
// ваш код здесь
// вы можете использовать FUNCTION RESTORE, чтобы восстановить выше сериализованные данные в целевой redis
}
}
});
replicator.open();
Коммерческая поддержка для redis-replicator
доступна. В настоящее время доступны следующие услуги:
Вы можете также связаться с Бао И Чен напрямую, отправив письмо по адресу chen.bao.yi@gmail.com.
27 января 2023 года, печальный день, когда я потерял свою мать 宁文君. Она поддерживала меня в разработке этого инструмента. Каждый раз, когда компания использовала этот инструмент, она радовалась как ребёнок и поощряла меня продолжать. Без неё я не смог бы поддерживать этот инструмент так долго. Даже если я не достиг многого, она всё ещё гордилась мной. Покойся с миром, и надеюсь, что Бог благословит её.
YourKit любезно поддерживает этот проект с открытым исходным кодом своим полнофункциональным профилировщиком Java.
YourKit, LLC является создателем инновационных и интеллектуальных инструментов для профилирования
приложений Java и .NET. Взгляните на ведущие программные продукты YourKit:
YourKit Java Profiler и
YourKit .NET Profiler.
IntelliJ IDEA — это интегрированная среда разработки (IDE) для создания компьютерного программного обеспечения на Java.
Она разработана JetBrains (ранее известной как IntelliJ). Redisson — это распределённая сетка данных в памяти на основе Redis для Java, предлагающая распределённые объекты и сервисы (BitSet
, Set
, Multimap
, SortedSet
, Map
, List
, Queue
, BlockingQueue
, Deque
, BlockingDeque
, Semaphore
, Lock
, AtomicLong
, CountDownLatch
, Publish / Subscribe
, Bloom filter
, Remote service
, Spring cache
, Executor service
, Live Object service
, Scheduler service
), которые поддерживаются сервером Redis.
Redisson предоставляет более удобный и простой способ работы с Redis. Объекты Redisson обеспечивают разделение задач, что позволяет сосредоточиться на моделировании данных и логике приложения.
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )