Redis có hỗ trợ master-slave replication như nhiều bạn đã biết: http://redis.io/topics/replication. Nhưng chuyện gì xảy ra nếu Master die? Làm cách nào để tự động chuyển Slave thành Master? Bài viết sau ghi lại cách thực hiện với NRPE (Nagios Remote Plugin Executor).
Mô hình:
- A: Nagios server
- B: Master Redis
- C: Slave Redis
Về ý tưởng: đơn giản là sẽ dùng Nagios monitor Redis trên B, nếu không kết nối được thì sẽ đẩy C lên làm Master.
Trên A, mình có định nghĩa một service thế này:
Code:
define service{
use critical-service
host_name B
service_description redis:2302
check_command check_tcp!2302
event_handler promote_slave_redis!C!2302
contact_groups admin-sms,admin
}
`promote_slave_redis` có nội dung như sau:
Code:
define command{
command_name promote_slave_redis
command_line $USER1$/eventhandlers/promote_slave_redis.sh $SERVICESTATE$ $SERVICESTATETYPE$ $SERVICEATTEMPT$ $ARG1$ $ARG2$
}
Nagios sẽ căn cứ vào mấy cái macro đầu tiên để quyết định khi nào thì gọi event handler. 2 arguments sau đó lần lượt là slave_redis:port.
Nội dung của event handler script có thể viết đơn giản như sau:
Code:
#!/bin/bash
case "$1" in
OK)
;;
WARNING)
;;
UNKNOWN)
/usr/local/nagios/libexec/check_nrpe -H $4 -c promote_slave_redis -a $5
;;
CRITICAL)
/usr/local/nagios/libexec/check_nrpe -H $4 -c promote_slave_redis -a $5
;;
esac
exit 0
$4, $5 lần lượt là host và port của slave Redis server.
Trên C (Slave), `promote_slave_redis` command được định nghĩa như sau:
Code:
command[promote_slave_redis]=/usr/lib64/nagios/plugins/promote_slave_redis.sh $ARG1$
Để có thể truyền arguments cho NRPE, các bạn cần 2 yêu cầu:
- compile with --enable-command-args
- set dont_blame_nrpe = 1
Nội dung của `promote_slave_redis.sh` chỉ gồm 1 lệnh thế này:
Code:
#!/bin/bash
echo 'slaveof no one' | /usr/local/redis/bin/redis-cli -h C -p $1
Restart NRPE trên C, Nagios trên A, thử stop Redis trên B, soi log Nagios bạn sẽ thấy:
[1329330131] SERVICE ALERT: B;redis:2302;CRITICAL;SOFT;1;Connection refused
[1329330131] SERVICE EVENT HANDLER: B;redis:2302;CRITICAL;SOFT;1;promote_slave_redis!C!2302
Trên một terminal khác, chạy một lệnh thế này:
Code:
$ watch 'echo "info" | redis-cli -h C -p 2302'
bạn sẽ thấy:
vm_enabled:0
role:slave
master_host:B
master_port:2302
master_link_status:up
master_last_io_seconds_ago:5
db0:keys=3,expires=0
được chuyển thành:
vm_enabled:0
role:master
db0:keys=3,expires=0
Làm tương tự để biến B thành slave khi nó online trở lại.