Redis Sentinel hoạt động như thế nào?

[Redis] Redis Sentinel hoạt động như thế nào?

Redis sentinel cung cấp một giải pháp HA cho cụm triển khai Redis. Nghĩa là, khi có một hoặc một số Redis instance down, thì cụm Redis của bạn vẫn hoạt động tốt.

Redis Sentinel được thiết kế để monitor và quản lý các Redis instances bằng cách thực hiện các task sau:

  • Monitoring: Sentinel check các master và slave nodes theo định kì để đảm bảo các node này luôn luôn hoạt động tốt.
  • Notification: Sentinel có thể send các notification alert khi có một redis instance failure thông tqua một API
  • Automatic failover: Nếu một Master bị fail, Sentinel sẽ khởi tạo một “Failover” process:

– Pick một running slave và promote SLAVE này lên làm Master

– Reconfigured các slaves còn lại thành slave của Master mới

– Reconfigured tất cả các Sentinel monitor Master mới

  • Configuration provider: Sentinel hoạt động như một “source of authority for client’s service discovery”. Client connect tới Sentinel để hỏi về địa chỉ của Current Redis Master, nếu một failover xảy ra, Sentinel sẽ report về cho client address của latest Redis Master (mới nhất).

Sentinel is a robust distributed system

Các Sentinel liên lạc với nhau, và cùng nhau quyết định rằng một “Master node là unreachable”. Quyết định được đưa ra dựa vào quorum value

Chú ý rằng, quorum value phải lớn hơn quá bán thì mới có ý nghĩa. Vì vậy, khi thiết kế, thường chọn số node cài sentinel là số lẻ: 3,5,7 …

Quorum Value

Là số lượng Sentinel đồng ý rằng Master node là unreachable. Giá trị này chỉ được dùng để detect failure.

How Redis offers High Availability and Automatic Failover ?

Khi Redis Master down, các Sentinel sẽ liên lạc với nhau và start một cuộc họp bàn:

  • Nếu số lượng Sentinel đồng ý promote một Slave lên làm Master thì quá trình Failover sẽ được start, một Slave sẽ trở thành Master mới. Các redis instance còn laị sẽ được reconfigure thành các slave của master mới.
  • Nếu số lượng Sentinel đồng ý promote một Slave lên làm Master nhỏ hơn quá bán thì quá trình Failover sẽ không diễn ra, hệ thống redis sẽ ngừng hoạt động do không có master mới.

Mô hình Redis Sentinel 2 Instances → Đừng bao giờ làm điều này 🙂

+----+         +----+
| M1 |---------| R1 |
| S1 | | S2 |
+----+ +----+

Configuration: quorum = 1
  • Instance1: Master M1 và sentinel S1
  • Instane2: Slave R1 và sentinel S2

Chuyện gì sẽ xảy ra:

  • Trong trường hợp Master M1 down, Sentinel S1 và Sentinel S2 Sẽ đồng ý và promote Slave R1 lên thành Master. Trong trường hợp này, số sentinel đồng ý là 2 (quá bán) nên quá trình failover sẽ được start.
  • Tuy nhiên, trong các trường hợp thông thường, khi instance 1 gặp sự cố, nghĩa là cả M1 và S1 đều down, khi ấy S2 không thể tương tác với S1, số lượng sentinel đồng ý promote R1 lên làm master là 1 => nhỏ hơn quá bán => quá trình failover không được start => hệ thống Redis sập (do không có slave nào được promote lên master thay thế).

Vì vậy, Mô hình Sentinel nên được setup trên ÍT NHẤT 3 instances, và thường được chọn là số lẻ.

Mô hình Redis Sentinel 3 instances

<strong jo>M hnh Redis 3 Instances</strong>

Mô hình:

Master Node: 10.140.0.11slave Node: 10.148.0.27Slave Node: 10.140.0.10

Trên mỗi node:

sudo apt-get update 
sudo apt-get install build-essential tcl
sudo apt-get install libjemalloc-dev (Optional)
curl -O http://download.redis.io/redis-stable.tar.gz
tar xzvf redis-stable.tar.gz
cd redis-stable

Config redis master node:

protected-mode no
port 6379
daemonize yes
pidfile “/var/run/redis.pid”
loglevel notice
logfile “/var/log/redis/redis.log”
databases 16

Config redis slave nodes:

protected-mode no
port 6379
daemonize yes
pidfile “/var/run/redis.pid”
loglevel notice
logfile “/var/log/redis/redis.log”
databases 16
slaveof 10.140.0.11 6379

Start Redis-server process:

./src/redis-server redis.conf

khi đó, check trên master node:

127.0.0.1:6379> info replication# Replicationrole:masterconnected_slaves:2slave0:ip=10.148.0.27,port=6379,state=online,offset=15851,lag=1slave1:ip=10.140.0.10,port=6379,state=online,offset=15851,lag=1master_replid:adcd85e20eebebd1369fab9543fa10ba9f65cab0master_replid2:0000000000000000000000000000000000000000master_repl_offset:15851second_repl_offset:-1repl_backlog_active:1repl_backlog_size:1048576repl_backlog_first_byte_offset:1repl_backlog_histlen:15851

Trên slave node:

127.0.0.1:6379> info replication# Replicationrole:slavemaster_host:10.140.0.11master_port:6379master_link_status:upmaster_last_io_seconds_ago:1master_sync_in_progress:0slave_repl_offset:12084slave_priority:100slave_read_only:1connected_slaves:0master_replid:adcd85e20eebebd1369fab9543fa10ba9f65cab0master_replid2:0000000000000000000000000000000000000000master_repl_offset:12084second_repl_offset:-1repl_backlog_active:1repl_backlog_size:1048576repl_backlog_first_byte_offset:1repl_backlog_histlen:12084

Data được sync từ Master sang các Slave node

  • Log trên Slave node:
root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.24162:S 06 May 2019 08:07:49.355 * DB loaded from disk: 0.000 seconds24162:S 06 May 2019 08:07:49.355 * Before turning into a replica, using my master parameters to synthesize a cached master: I may be able to synchronize with the new master with just a partial transfer.24162:S 06 May 2019 08:07:49.355 * Ready to accept connections24162:S 06 May 2019 08:07:49.356 * Connecting to MASTER 10.140.0.11:637924162:S 06 May 2019 08:07:49.356 * MASTER <-> REPLICA sync started24162:S 06 May 2019 08:07:49.405 # Error condition on socket for SYNC: Connection refused24162:S 06 May 2019 08:07:50.359 * Connecting to MASTER 10.140.0.11:637924162:S 06 May 2019 08:07:50.359 * MASTER <-> REPLICA sync started24162:S 06 May 2019 08:07:50.408 # Error condition on socket for SYNC: Connection refused24162:S 06 May 2019 08:07:51.362 * Connecting to MASTER 10.140.0.11:637924162:S 06 May 2019 08:07:51.363 * MASTER <-> REPLICA sync started24162:S 06 May 2019 08:07:51.411 # Error condition on socket for SYNC: Connection refused24162:S 06 May 2019 08:07:52.367 * Connecting to MASTER 10.140.0.11:637924162:S 06 May 2019 08:07:52.368 * MASTER <-> REPLICA sync started24162:S 06 May 2019 08:07:52.416 * Non blocking connect for SYNC fired the event.24162:S 06 May 2019 08:07:52.465 * Master replied to PING, replication can continue...24162:S 06 May 2019 08:07:52.563 * Trying a partial resynchronization (request 9c3a5c583cb71c9a4fd59fab91edda0c8d3af61a:1).24162:S 06 May 2019 08:07:52.613 * Full resync from master: adcd85e20eebebd1369fab9543fa10ba9f65cab0:024162:S 06 May 2019 08:07:52.614 * Discarding previously cached master state.24162:S 06 May 2019 08:07:52.634 * MASTER <-> REPLICA sync: receiving 175 bytes from master24162:S 06 May 2019 08:07:52.634 * MASTER <-> REPLICA sync: Flushing old data24162:S 06 May 2019 08:07:52.634 * MASTER <-> REPLICA sync: Loading DB in memory24162:S 06 May 2019 08:07:52.634 * MASTER <-> REPLICA sync: Finished with success
  • Log trên master Node:
26581:M 06 May 2019 08:07:51.504 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.26581:M 06 May 2019 08:07:51.504 # Server initialized26581:M 06 May 2019 08:07:51.504 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.26581:M 06 May 2019 08:07:51.505 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.26581:M 06 May 2019 08:07:51.505 * DB loaded from disk: 0.000 seconds26581:M 06 May 2019 08:07:51.505 * Ready to accept connections26581:M 06 May 2019 08:07:52.587 * Replica 10.148.0.27:6379 asks for synchronization26581:M 06 May 2019 08:07:52.588 * Partial resynchronization not accepted: Replication ID mismatch (Replica asked for '9c3a5c583cb71c9a4fd59fab91edda0c8d3af61a', my replication IDs are '2981f35caad816d7bd89381f503a669f000926f1' and '0000000000000000000000000000000000000000')26581:M 06 May 2019 08:07:52.588 * Starting BGSAVE for SYNC with target: disk26581:M 06 May 2019 08:07:52.588 * Background saving started by pid 2659726597:C 06 May 2019 08:07:52.592 * DB saved on disk26597:C 06 May 2019 08:07:52.592 * RDB: 0 MB of memory used by copy-on-write26581:M 06 May 2019 08:07:52.609 * Background saving terminated with success26581:M 06 May 2019 08:07:52.609 * Synchronization with replica 10.148.0.27:6379 succeeded26581:M 06 May 2019 08:08:02.559 * Replica 10.140.0.10:6379 asks for synchronization26581:M 06 May 2019 08:08:02.560 * Partial resynchronization not accepted: Replication ID mismatch (Replica asked for '8cef21c6102a924ff9f293c112b68dc363ce6bec', my replication IDs are 'adcd85e20eebebd1369fab9543fa10ba9f65cab0' and '0000000000000000000000000000000000000000')26581:M 06 May 2019 08:08:02.560 * Starting BGSAVE for SYNC with target: disk26581:M 06 May 2019 08:08:02.560 * Background saving started by pid 2676626766:C 06 May 2019 08:08:02.564 * DB saved on disk26766:C 06 May 2019 08:08:02.564 * RDB: 0 MB of memory used by copy-on-write26581:M 06 May 2019 08:08:02.644 * Background saving terminated with success26581:M 06 May 2019 08:08:02.644 * Synchronization with replica 10.140.0.10:6379 succeeded

Log thông báo data đã được sync sang các slave thành công.

Setup và configure Sentinel

Sentinel được cài trên tất cả các node.

Config cho Sentinel:

protected-mode no
port 26379
daemonize yes
pidfile "/var/run/redis-sentinel.pid"
logfile "/var/log/redis/sentinel-01.log"
dir .
sentinel deny-scripts-reconfig yes
sentinel monitor mymaster 10.140.0.11 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 10000

Config này là giống nhau cho tất cả các Sentinel node. Sentinel sẽ monitor tất cả các redis node. Thông tin master node tại:

sentinel monitor mymaster 10.140.0.11 6379 2

Trong đó, 2 là Quorum value, nghiã là Master được gọi là down khi có ≥ sentinel đồng ý với quyết định này

Thông tin của các slave node sẽ được sentinels lấy ra từ Master node.

Trên các sentinel node start các Sentinel process:

./src/redis-server sentinel.conf — sentinel &

Khi đó, tất cả các Sentinel đều connect thông tin của Master:

3426:X 06 May 2019 08:07:47.016 # -sdown slave 10.140.0.10:6379 10.140.0.10 6379 @ mymaster 10.140.0.11 63793426:X 06 May 2019 08:07:49.586 * +reboot slave 10.148.0.27:6379 10.148.0.27 6379 @ mymaster 10.140.0.11 63793426:X 06 May 2019 08:07:49.588 # -sdown slave 10.148.0.27:6379 10.148.0.27 6379 @ mymaster 10.140.0.11 63793426:X 06 May 2019 08:07:52.138 * +reboot master mymaster 10.140.0.11 63793426:X 06 May 2019 08:07:52.238 # -sdown master mymaster 10.140.0.11 63793426:X 06 May 2019 08:07:52.238 # -odown master mymaster 10.140.0.11 6379

Redis Sentinel Automatic Failover

Redis Sentinel monitor Master node, nếu Master down, quá trình Failover sẽ được start.

Thử Stop redis trên master node. Khi đó:

Sentinel log trên Slave node:

14582:X 06 May 2019 08:07:52.461 # -odown master mymaster 10.140.0.11 637914582:X 06 May 2019 08:08:01.979 * +convert-to-slave slave 10.140.0.10:6379 10.140.0.10 6379 @ mymaster 10.140.0.11 637914582:X 06 May 2019 09:03:40.382 # +sdown master mymaster 10.140.0.11 637914582:X 06 May 2019 09:03:40.474 # +odown master mymaster 10.140.0.11 6379 #quorum 2/214582:X 06 May 2019 09:03:40.474 # +new-epoch 2414582:X 06 May 2019 09:03:40.474 # +try-failover master mymaster 10.140.0.11 637914582:X 06 May 2019 09:03:40.478 # +vote-for-leader 6d636ad5286eb9b924675161bfebe9f213c4a20f 2414582:X 06 May 2019 09:03:40.510 # fc858414cd54fc700a57c46f1e1cd04ab98a0be9 voted for 6d636ad5286eb9b924675161bfebe9f213c4a20f 2414582:X 06 May 2019 09:03:40.529 # e4cdc92722de43fd5feedbb6490b307fbb440f2c voted for e4cdc92722de43fd5feedbb6490b307fbb440f2c 2414582:X 06 May 2019 09:03:51.057 # -failover-abort-not-elected master mymaster 10.140.0.11 637914582:X 06 May 2019 09:03:51.135 # Next failover delay: I will not start a failover before Mon May  6 09:04:00 201914582:X 06 May 2019 09:04:00.679 # +new-epoch 2514582:X 06 May 2019 09:04:00.682 # +vote-for-leader e4cdc92722de43fd5feedbb6490b307fbb440f2c 2514582:X 06 May 2019 09:04:00.690 # Next failover delay: I will not start a failover before Mon May  6 09:04:21 201914582:X 06 May 2019 09:04:01.045 # +config-update-from sentinel e4cdc92722de43fd5feedbb6490b307fbb440f2c 10.148.0.27 26379 @ mymaster 10.140.0.11 637914582:X 06 May 2019 09:04:01.046 # +switch-master mymaster 10.140.0.11 6379 10.140.0.10 637914582:X 06 May 2019 09:04:01.046 * +slave slave 10.148.0.27:6379 10.148.0.27 6379 @ mymaster 10.140.0.10 637914582:X 06 May 2019 09:04:01.047 * +slave slave 10.140.0.11:6379 10.140.0.11 6379 @ mymaster 10.140.0.10 637914582:X 06 May 2019 09:04:06.096 # +sdown slave 10.140.0.11:6379 10.140.0.11 6379 @ mymaster 10.140.0.10 6379

Khi đó, một Slave sẽ được vode lên role Master.

Và sentinel được update config:

sentinel monitor mymaster 10.140.0.11 6379 2

Trở thành:

sentinel monitor mymaster 10.140.0.10 6379 2

Đồng thời, config file của các node Slave còn lại cũng được update address của master mới:

Từ:

slaveof 10.140.0.11 6379

Trở thành:

slaveof 10.140.0.10 6379

Đó là lý do, Sentinel còn được gọi là configuration provider.

Setup HA Proxy cho Redis HA.

Câu hỏi đặt ra: Với một mô hình 3 node Redis như trên, vậy làm thế nào để client xác định được address của Redis Master?

HA proxy là một trong các solutions.

HA proxy (High Availability Proxy) là một open-source Load-balancer cho phép load balance TCP services. HA proxy sẽ check xem trong các redis node, node nào có vai trò là Master. Từ đó, các request qua HA proxy server sẽ được forward đến Redis Master node.

Cài đặt:

apt-get install haproxy

file config của HA proxy tại /etc/haproxy/haproxy.conf

Thay đổi như sau:

# Specifies TCP timeout on connect for use by the frontend ft_redis# Set the max time to wait for a connection attempt to a server to succeed# The server and client side expected to acknowledge or send data.defaults REDISmode tcptimeout connect 3stimeout server 6stimeout client 6s# Specifies listening socket for accepting client connections using the default# REDIS TCP timeout and backend bk_redis TCP health check.frontend ft_redisbind 0.0.0.0:6378 name redisdefault_backend bk_redis# Specifies the backend Redis proxy server TCP health settings# Ensure it only forward incoming connections to reach a master.backend bk_redisoption tcp-checktcp-check connecttcp-check send PINGrntcp-check expect string +PONGtcp-check send info replicationrntcp-check expect string role:mastertcp-check send QUITrntcp-check expect string +OKserver redis_01 10.140.0.10:6379 check inter 1sserver redis_02 10.140.0.11:6379 check inter 1sserver redis_02 10.148.0.27:6379 check inter 1s

Trong đó:

bind 0.0.0.0:6378 name redis

Là địa chỉ để client connect tới. Khi client connect tới ha-proxy IP + port 6378, request sẽ được forward tới Redis Master

server redis_01 10.140.0.10:6379 check inter 1s

server redis_02 10.140.0.11:6379 check inter 1s

server redis_02 10.148.0.27:6379 check inter 1s

Set các Redis node:

tcp-check send info replicationrn
tcp-check expect string role:master

Gửi câu lệnh sang các redis nodes, lấy IP của node có role master. Khi đó, các request sẽ được forward đến master node

Thử connect đến redis master thông qua ha proxy server, port 6378:

  • 10.140.0.12: IP của HA proxy
~/redis-01/redis-stable# redis-cli -h 10.140.0.12 -p 637810.140.0.12:6378> info replication# Replicationrole:masterconnected_slaves:1slave0:ip=10.140.0.11,port=6379,state=online,offset=1145239,lag=1master_replid:c5fdadbc6a77166d3cc4d845a7add532b66d9e65master_replid2:6b93c5b5a3babfbdafe4c7f42dd8065960f7eb7bmaster_repl_offset:1145239second_repl_offset:823027repl_backlog_active:1repl_backlog_size:1048576repl_backlog_first_byte_offset:96664repl_backlog_histlen:104857610.140.0.12:6378>

Qua bài viết này, các bạn đã phần nào nắm được cách thức hoạt động cũng như cách setup một mô hình Redis Sentinel. Để bài viết dễ hiểu, các câú hình cho Redis và Sentinel được setup một cách đơn giản nhất.

Các bạn có thể tham khảo thêm một số link sau:

https://redis.io/topics/sentinel

https://www.howtoforge.com/tutorial/ubuntu-load-balancer-haproxy/

https://medium.com/@amila922/redis-sentinel-high-availability-everything-you-need-to-know-from-dev-to-prod-complete-guide-deb198e70ea6