Конструкция и принцип кластера Redis

Java задняя часть
Конструкция и принцип кластера Redis

1. Режим стража

До redis3.0 архитектура Sentinel, используемая Redis, которая отслеживает состояние главного узла с помощью инструмента Sentinel; если главный узел неисправен, будет выполнено переключение ведущий-ведомый, и будет использоваться ведомый. как мастер.

Недостатки режима Sentinel:

(1) Когда мастер повесит трубку, часовой выберет мастера.Во время выборов нет возможности получить доступ к Redis, он будет существоватьМгновенный доступЕсли мастер зависнет во время большой акции на сайте интернет-магазина, за несколько секунд будет потеряно много данных о заказе;

(2) Режим Sentinel, внешнийТолько главный узел может писать, подчиненный узел может использоваться только для чтения. Хотя один узел Redis поддерживает максимальное количество запросов в секунду, равное 10 Вт, во время продвижения электронной коммерции вся нагрузка по записи данных ложится на главный узел.

(3) Память одного узла Redis не может быть установлена ​​слишком большой.Если данные слишком велики, синхронизация ведущий-ведомый будет очень медленной, когда узел запускается, время очень велико (подчиненный узел имеет все данные мастер-узла)

2. Кластер Redis

1. Введение в кластер Redis

Кластер Redis — этоНесколько групп узлов master-slaveсостоит из распределенных сервисных кластеров, которыеРепликация, высокая доступность и разделениехарактеристика. Кластер Redis не нуждается в Sentinel Sentinel для выполнения функции удаления узлов и аварийного переключения. Каждый узел должен быть установлен в режим кластера.Этот режим кластера не имеет центрального узла и может масштабироваться горизонтально.Согласно официальным документам, он может быть линейно расширен до десятков тысяч узлов (официально рекомендуется не более 1000 узлов). Производительность и высокая доступность кластера Redis лучше, чем в дозорном режиме предыдущей версии, а конфигурация кластера очень проста.

2. Преимущества кластера Redis:

(1) Кластер Redis имеет несколько мастеров, которые могутУменьшите влияние проблем прерывания доступа;

Если мастер в кластере завис, то необходимо записать данные на этот мастер, и эту операцию нужно подождать какое-то время, однако запись данных на другие мастер-ноды не затрагивается.

(2) Кластер Redis имеет несколько мастеров, что может обеспечить более высокий параллелизм;

(3) Кластер Redis можно хранить в осколках, чтобы можно было хранить больше данных;

3. Построение кластера Redis

Кластерная конструкция RedisТребуется как минимум 3 мастер-ноды, здесь мы строим 3 мастера, каждый с ведомым узлом, всего 6 узлов Redis; (3 машины, на каждой машине есть ведущая и ведомая)

Первая машина: 192.168.1.1 8001 порт 8002 порт

2-я машина: 192.168.1.2 8001 порт 8002 порт

3-я машина: 192.168.1.3 8001 порт 8002 порт

первый шаг: Создать папку

mkdir -p /usr1/redis/redis-cluster/8001 /usr1/redis/redis-cluster/8002

второй шаг: Скопируйте файл redis.conf из каталога установки redis в каталог 8001 соответственно.

cp /usr1/redis-5.0.3/redis.conf /usr1/redis/redis-cluster/8001

третий шаг: изменить следующее содержимое файла redis.conf

port 8001 daemonize yes
pidfile "/var/run/redis\_8001.pid" #指定数据文件存放位置,必须要指定不同的目录位置,不然会丢失数据 dir /usr1/redis/redis-cluster/8001/ #启动集群模式
cluster\-enabled yes

#集群节点信息文件,这里800x最好和port对应上
cluster\-config-file nodes-8001.conf

# 节点离线的超时时间
cluster\-node-timeout 5000 #去掉bind绑定访问ip信息
#bind 127.0.0.1 #关闭保护模式
protected\-mode no 

#启动AOF文件
appendonly yes

#如果要设置密码需要增加如下配置:
#设置redis访问密码
requirepass redis\-pw

#设置集群节点间访问密码,跟上面一致
masterauth redis\-pw

четвертый шаг, скопируйте измененный файл конфигурации выше в папку 8002 и измените 8001 на 8002:

cp /usr1/redis/redis-cluster/8001/redis.conf /usr1/redis/redis-cluster/8002 cd /usr1/redis/redis-cluster/8002/ vim redis.conf

#批量修改字符串
:%s/8001/8002/g

пятый шаг, скопируйте файлы с машины (192.168.1.1) на две другие машины

scp /usr1/redis/redis-cluster/8001/redis.conf  root@192.168.1.2:/usr1/redis/redis-cluster/8001/
scp /usr1/redis/redis-cluster/8002/redis.conf  root@192.168.1.2:/usr1/redis/redis-cluster/8002/  
 scp /usr1/redis/redis-cluster/8001/redis.conf  root@192.168.1.3:/usr1/redis/redis-cluster/8001/
scp /usr1/redis/redis-cluster/8002/redis.conf  root@192.168.1.3:/usr1/redis/redis-cluster/8002/

Шестой шаг, запустите эти 6 экземпляров redis соответственно, а затем проверьте, успешно ли запущен запуск.

/usr1/redis/redis-5.0.3/src/redis-server /usr1/redis/redis-cluster/8001/redis.conf /usr1/redis/redis-5.0.3/src/redis-server /usr1/redis/redis-cluster/8002/redis.conf   
ps -ef | grep redis

Шаг 7,использоватьredis-cli создает весь кластер Redis(Рубиновый скрипт redis-trib.rb, использовавшийся до redis 5.0)

Запустите приведенную выше команду, чтобы завершить сборку

/usr1/redis/redis-5.0.3/src/redis-cli -a redis-pw --cluster create --cluster-replicas 1 192.168.1.1:8001 192.168.1.1:8002 192.168.1.2:8001 192.168.1.2:8002 192.168.1.3:8001 192.168.1.3:8002

инструкция:

-а : пароль;

--cluster-replicas 1: указывает, что 1 ведомое устройство подключено к 1 главному; --cluster-replicas 2: указывает, что 2 ведомых устройства подключены к 1 главному.

расширять:

См. команду справки: src/redis-cli --cluster help

create:创建一个集群环境host1:port1 ... hostN:portN
call:可以执行redis命令
add\-node:将一个节点添加到集群里,第一个参数为新节点的ip:port,第二个参数为集群中任意一个已经存在的节点的ip:port
del\-node:移除一个节点
reshard:重新分片
check:检查集群状态

Шаг 8, проверьте кластер

(1) Подключиться к любому клиенту

/usr1/redis/redis-5.0.3/src/redis-cli -a redis-pw -c -h 192.168.1.1 -p 8001

Описание: -a указывает пароль сервера; -c указывает режим кластера; -h указывает ip-адрес; -p указывает номер порта

(2) Просмотр информации о кластере: информация о кластере

(3) Просмотрите список узлов: ведущий, соответствующий ведомому узлу кластера, также можно увидеть из приведенного выше;

Из приведенного выше видно, под каким хозяином висит раб;

Информация об узле хранится в файле /usr1/redis/redis-cluster/8001/nodes-8001.conf;

(4) выполнить проверку операций с данными;

(5) Чтобы закрыть кластер, нужно закрыть по одному, используйте команду:

/usr/local/redis‐5.0.3/src/redis‐cli ‐a redis-pw ‐c ‐h 192.168.1.1 ‐p 8001 shutdown /usr/local/redis‐5.0.3/src/redis‐cli ‐a redis-pw ‐c ‐h 192.168.1.1 ‐p 8002 shutdown
......

Уведомление: при создании кластера необходимо отключить противопожарную защиту на всех машинах узла, чтобы гарантировать, что порт службы Redis и порт сплетен для связи узла кластера могут быть переданы;

systemctl stop firewalld # Временно закрыть брандмауэр

systemctl disable firewalld # Отключить запуск

4. Принципиальный анализ кластера Redis

Redis Cluster делит все данные на16384слотов, каждый узел отвечает за часть слотов. Информация о слоте хранится в каждом узле. Слот будет выделен только главному узлу, а подчиненному узлу слот не будет выделен.

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

Алгоритм расположения слота

По умолчанию Cluster использует алгоритм crc16 для хеширования значения ключа для получения целочисленного значения, а затем использует это целочисленное значение для сопряжения16384Возьмите модуль, чтобы получить конкретный слот.

HASH_SLOT = CRC16(key) % 16384

прыжок

Когда клиент отправляет инструкцию узлу, сначала текущий узел вычисляет ключ инструкции, чтобы получить информацию о слоте, и решает, управляется ли рассчитанный слот текущим узлом; если слот не управляется текущим узлом , то он сообщит клиенту. Клиент отправляет специальную инструкцию перехода, содержащую адрес узла целевой операции, сообщая клиенту о подключении к этому узлу для получения данных. После того, как клиент получит инструкцию, помимо перехода к нужному узлу для работы, он также синхронно обновит и исправит локальный кэш таблицы сопоставления слотов, и все последующие ключи будут использовать новую таблицу сопоставления слотов.

Механизм связи между узлами кластера Redis

Существует два способа поддерживать метаданные кластера: централизованный и сплетни.Связь между узлами кластера Redis использует для связи протокол сплетен.

(1) Централизованно:

Преимущества: обновление и чтение метаданных очень чувствительны ко времени.Как только метаданные изменяются, они будут немедленно обновлены в централизованном хранилище, и другие узлы могут сразу же воспринять их, когда они будут прочитаны;

Недостатки: все требования к обновлению метаданных сосредоточены в одном месте, что может привести к увеличению нагрузки на хранилище метаданных. зоопарк использует этот метод

(2) сплетни:

Протокол сплетен содержит множество сообщений, включая пинг, понг, встречу, неудачу и другие. .

Преимущества: обновление метаданных относительно разбросано, а не сосредоточено в одном месте, и запросы на обновление будут последовательно отправляться на все узлы для обновления, что имеет определенную задержку и снижает нагрузку;

Недостаток: задержка обновления метаданных может привести к задержке некоторых операций кластера.

У каждого узла есть выделенный порт для связи между узлами, который является номером порта, который предоставляет услуги сам по себе + 10000, например 7001, тогда порт 17001 используется для связи между узлами. Каждый узел отправляет сообщения проверки связи нескольким другим узлам через равные промежутки времени и возвращает сообщения проверки связи после получения сообщений проверки связи в других точках.

сетевой джиттер

Дрожание сети — очень распространенное явление, когда некоторые соединения вдруг становятся недоступными, а затем быстро приходят в норму.
Для решения этой проблемы Redis Cluster предоставляет опцию cluster-node-timeout, которая означает, что при отключении узла дольше настроенного таймаута можно определить, что узел неисправен и требуется переключение master-slave. Без этой опции джиттер сети вызывал бы частые переключения ведущий-ведомый (повторная репликация данных).

Принцип выбора кластера Redis

Когда ведомое устройство обнаруживает, что его ведущее устройство находится в состоянии сбоя, оно пытается выполнить отработку отказа, чтобы стать новым ведущим. Поскольку у мертвого мастера есть несколько ведомых, эти ведомые будут конкурировать, чтобы стать главными узлами.Процесс выглядит следующим образом:

(1) Как slave1, так и slave2 обнаружили, что главный статус их соединения стал Fail;

(2) Они добавляют 1 к кластеру currentEpoch (цикл выборов), записанному ими самими, и используют протокол сплетен для передачи информации FailOver_auth_request;

(3) Другие узлы получают сообщения от ведомого1 и ведомого2 (отвечает только ведущий), оценивают достоверность запроса и отправляют FailOver_auth_ack ведомому1 или ведомому2 (только одно подтверждение для каждой эпохи); в избирательном цикле мастер будет только ответить первому ведомому, отправившему ему сообщение;

(4) slave1 собирает возвращенный FailOver_auth_ack, он получаетАкки есть больше чем у половины мастеровЗатем он становится новым мастером (поэтому в кластере нужно как минимум 3 мастера. Если мастеров всего два, после зависания одного из них остается только один мастер-узел, который не может быть успешно избран)

(5) Новый главный узел широковещательно передает сообщение Pong, чтобы уведомить другие узлы кластера, и нет необходимости выбирать снова.

Ведомый узел не пытается инициировать выбор, как только ведущий узел переходит в состояние FAIL, но есть определенная задержка.Задержка гарантирует, что мы ждем, пока состояние FAIL распространится по кластеру., если ведомое устройство попытается сделать выбор немедленно, другие ведущие устройства могут не понять статус FAIL и отказаться голосовать.

Формула расчета задержки:DELAY = 500ms + random(0 ~ 500ms) + SLAVE_RANK * 1000ms

SLAVE_RANK: ранг, представляющий общий объем данных, которые этот ведомый реплицировал от ведущего. Чем меньше ранг, тем новее реплицированные данные. Таким образом, ведомое устройство, содержащее последние данные, первым инициирует выборы (теоретически).

Почему для кластера Redis требуется как минимум три главных узла, а рекомендуемое количество узлов нечетное?
Поскольку для успешного избрания нового мастера требуется согласие более половины мастер-узлов кластера, при наличии только двух мастер-узлов при выходе из строя одного из них условия для выбора нового мастера не могут быть соблюдены.
Нечетное количество мастер-узлов может сохранить один узел на основе выполнения условия выбора.Например, по сравнению с кластером из трех мастер-узлов и четырех мастер-узлов, если каждый повесит трубку мастер-узла, они могут выбрать новый мастер-узел. , Два главных узла не могут выбрать новый главный узел, поэтому главный узел с нечетным номером больше подходит с точки зрения экономии машинных ресурсов.

Полнота кластера может предоставлять внешние сервисы
Если в конфигурации cluster-require-full-coverage в redis.conf указано значение no, это означает, что при отключении главной библиотеки, отвечающей за слот, и отсутствии соответствующей подчиненной библиотеки для восстановления после сбоя кластер по-прежнему доступен. да, кластер недоступен.

5. Java-операция Кластер Redis

метод первый(Джедаи):

(1) Ввести координаты maven джедаев

<dependency\>
 <groupId\>redis.clients</groupId\>
 <artifactId\>jedis</artifactId\>
 <version\>2.9.0</version\>
</dependency\>

(2) Код, написанный на Java, выглядит следующим образом:

public class JedisClusterTest { public static void main(String\[\] args) throws IOException {
 
        JedisPoolConfig config \= new JedisPoolConfig();
        config.setMaxTotal(20);
        config.setMaxIdle(10);
        config.setMinIdle(5);

        Set<HostAndPort> jedisClusterNode = new HashSet<HostAndPort>();
        jedisClusterNode.add(new HostAndPort("192.168.1.1", 8001));
        jedisClusterNode.add(new HostAndPort("192.168.1.1", 8002));
        jedisClusterNode.add(new HostAndPort("192.168.1.2", 8001));
        jedisClusterNode.add(new HostAndPort("192.168.1.2", 8002));
        jedisClusterNode.add(new HostAndPort("192.168.1.3", 8001));
        jedisClusterNode.add(new HostAndPort("192.168.1.3", 8002));
        JedisCluster jedisCluster \= null; try { //connectionTimeout:指的是连接一个url的连接等待时间 //soTimeout:指的是连接上一个url,获取response的返回等待时间
             jedisCluster = new JedisCluster(jedisClusterNode, 6000, 5000, 10, "redis-pw", config);
             System.out.println(jedisCluster.set("name", "zhangsan"));
             System.out.println(jedisCluster.get("name"));
         } catch (Exception e) {
            e.printStackTrace();
         } finally { if (jedisCluster != null) {
                jedisCluster.close();
             }
        }
    }
}

Способ 2: SpringBoot интегрирует Redis

(1) Ввести координаты maven

<dependency\>
 <groupId\>org.springframework.boot</groupId\>
 <artifactId\>spring‐boot‐starter‐data‐redis</artifactId\>
</dependency\>
 
<dependency\>
 <groupId\>org.apache.commons</groupId\>
 <artifactId\>commons‐pool2</artifactId\>
</dependency\>

(2) Файл конфигурации

server:
  port: 8080 spring:
  redis:
  database: 0 timeout: 3000 password: redis\-pw
  cluster:
    nodes: 192.168.0.61:8001,192.168.0.62:8002,192.168.0.63:8003,192.168.0.61:8004,192.168.0.62:8005,192.168.0.6
3:8006 lettuce:
  pool:
  max‐idle: 50 min‐idle: 10 max‐active: 100 max‐wait: 1000

(3) код Java, как показано ниже:

@RestController public class TestController { private static final Logger logger = LoggerFactory.getLogger(TestController.class);

    @Autowired private StringRedisTemplate stringRedisTemplate;

    @RequestMapping("/test\_cluster") public void testCluster() throws InterruptedException {
        stringRedisTemplate.opsForValue().set("user:name", "wangwu");
        System.out.println(stringRedisTemplate.opsForValue().get("user:name"));
    }
}

Автор: ветер стоп дождь перерыв Ссылка на сайт:Блог Woohoo.cn на.com/Yufeng218/Afraid…Источник: cnblogs