65.9K
CodeProject 正在变化。 阅读更多。
Home

Redis:复制,第 3 部分 – redis-py 和使用 Python 从 Redis Sentinel 工作

emptyStarIconemptyStarIconemptyStarIconemptyStarIconemptyStarIcon

0/5 (0投票)

2019 年 4 月 3 日

CPOL

2分钟阅读

viewsIcon

5289

redis-py 库以及从 Python 使用 Redis Sentinel

继续讨论 Redis 复制和 Redis Sentinel – 使用 Python 的 redis-py 库的几个例子。

之前的系列文章

  1. Redis:复制,第 1 部分 – 概述。复制与分片。Sentinel 与集群。Redis 拓扑
  2. Redis:复制,第 2 部分 – 主从复制和 Redis Sentinel

所有 Python 的 Redis 客户端都可以在这里找到 – redis.io/clients

首先,我们将使用 redis-py 而不使用 Sentinel,只是为了检查它的工作方式。

然后 – 我们将启动 Sentinel 并检查主服务器和从服务器的发现情况。

一个工作环境,即 Redis 复制和 Redis Sentinel 已经在 之前的文章 中配置好了 – 这里只是 Python 的例子。

redis-py 和 Redis

在 Debian 上安装 redis-py

root@redis-0:/home/admin# apt install python-redis

此外,可以使用 pip,但我更喜欢使用正常的存储库。

检查一下

root@redis-0:/home/admin# python
Python 2.7.13 (default, Sep 26 2018, 18:42:22)
[GCC 6.3.0 20170516] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import redis
>>> r = redis.Redis(host='localhost', port=6379, db=0)
>>> r.get('test')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.7/dist-packages/redis/client.py", line 880, in get
return self.execute_command('GET', name)
File "/usr/lib/python2.7/dist-packages/redis/client.py", line 573, in execute_command
return self.parse_response(connection, command_name, **options)
File "/usr/lib/python2.7/dist-packages/redis/client.py", line 585, in parse_response
response = connection.read_response()
File "/usr/lib/python2.7/dist-packages/redis/connection.py", line 582, in read_response
raise response
redis.exceptions.ResponseError: NOAUTH Authentication required.

好的,有效。

在文档中找到授权

>>> help(redis.Redis)

添加 password

>>> r = redis.Redis(host='localhost', password='foobared', port=6379, db=0)
>>> r.get('test')
'test'

好的。

redis-py 和 Redis Sentinel

现在运行 Sentinel 实例(如果它们尚未启动),让我们通过 Redis Sentinel 集群客户端尝试 Redis。

主机上的 Sentinel 配置 /etc/redis/sentinel.conf 现在是

sentinel monitor redis-test 52.58.69.184 6379 2
sentinel down-after-milliseconds redis-test 6001
sentinel failover-timeout redis-test 60000
bind 0.0.0.0
sentinel auth-pass redis-test foobared

在 Sentinel 实例启动后 – 它将更新配置,因此现在在 redis-1 (这里是第一个从服务器) 上,配置看起来像

admin@redis-1:~$ cat /etc/redis/sentinel.conf
sentinel myid e3e62e6577aa975f93346dad3d4f8e25833fd8f1
sentinel monitor redis-test 52.29.101.118 6379 2
sentinel down-after-milliseconds redis-test 6001
bind 0.0.0.0
sentinel failover-timeout redis-test 60000
Generated by CONFIG REWRITE
port 26379
dir "/home/admin"
sentinel auth-pass redis-test foobared
sentinel config-epoch redis-test 1
sentinel leader-epoch redis-test 1
sentinel known-slave redis-test 52.58.69.184 6379
sentinel known-slave redis-test 35.159.18.26 6379
sentinel known-sentinel redis-test 172.31.46.202 26379 e0fe655c59aa3cc32eab1c0858c52418700abe79
sentinel known-sentinel redis-test 172.31.41.39 26379 07a450af0d2f178410b78ee0f5ae99ce1cd0ac62
sentinel current-epoch 1

检查 Sentinel 集群状态

root@redis-0:/home/admin# redis-cli -p 26379 info sentinel
Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=redis-test,status=ok,address=52.58.69.184:6379,slaves=2,sentinels=3

并使用 redis-py

>>> from redis.sentinel import Sentinel
>>> sentinel = Sentinel([('localhost', 26379)], socket_timeout=0.1)

您可以使用 discover_master() 方法获取主服务器的 IP 地址

>>> sentinel.discover_master('redis-test')
('52.58.69.184', 6379)

和从服务器

>>> sentinel.discover_slaves('redis-test')
[('52.29.101.118', 6379), ('35.159.18.26', 6379)]

要与主服务器一起工作,请使用 master_for() 方法

| master_for(self, service_name, redis_class=<class ‘redis.client.StrictRedis’>, 
connection_pool_class=<class ‘redis.sentinel.SentinelConnectionPool’>, **kwargs)
| Returns a redis client instance for the “service_name“ master.
>>> master = sentinel.master_for('redis-test', socket_timeout=0.1)

但是如果现在调用主服务器 – 它会告诉我们我们没有授权

>>> master.set('test-key', 'test-value')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.7/dist-packages/redis/client.py", line 1072, in set
return self.execute_command('SET', *pieces)
File "/usr/lib/python2.7/dist-packages/redis/client.py", line 573, in execute_command
return self.parse_response(connection, command_name, **options)
File "/usr/lib/python2.7/dist-packages/redis/client.py", line 585, in parse_response
response = connection.read_response()
File "/usr/lib/python2.7/dist-packages/redis/sentinel.py", line 55, in read_response
return super(SentinelManagedConnection, self).read_response()
File "/usr/lib/python2.7/dist-packages/redis/connection.py", line 582, in read_response
raise response
redis.exceptions.ResponseError: NOAUTH Authentication required.

因此,在创建 master 对象时 – 添加 password

>>> master = sentinel.master_for('redis-test', socket_timeout=0.1, password='foobared')

现在检查一下

>>> master.set('test-key', 'test-value')
True

此外,您可以获得整个主服务器的配置

>>> master.config_get()
{'appendonly': 'no', ... 'slave-announce-port': '0'}

或者以更易读的视图

>>> for i in master.config_get():
...   print(i)
...
appendonly
requirepass
daemonize
protected-mode
zset-max-ziplist-entries
zset-max-ziplist-value
dir
slave-serve-stale-data
cluster-require-full-coverage
slowlog-log-slower-than
masterauth
rdbchecksum
...

在从服务器上 – 检查我们之前添加的密钥

admin@redis-1:~$ redis-cli -a foobared get test-key
"test-value"

使用从服务器类似于主服务器

>>> slave = sentinel.slave_for('redis-test', socket_timeout=0.1, password='foobared')
>>> slave.get('test-key')
'test-value'

主服务器更改和 Sentinel 故障转移

让我们检查一下此时的主服务器

>>> sentinel.discover_master('redis-test')
('52.58.69.184', 6379)

最后,让我们尝试停止 redis-0 主机上的 Redis 主服务器

root@redis-0:/home/admin# systemctl stop redis-server

或者通过

root@redis-0:/home/admin# redis-cli -a foobared DEBUG sleep 600

(如果只用 kill 杀死 redis-server 进程 – Sentinel 会再次重启它)。

检查 Sentinel 的日志

10633:X 01 Apr 13:46:10.430 # +sdown master redis-test 52.58.69.184 6379
10633:X 01 Apr 13:46:10.486 # +odown master redis-test 52.58.69.184 6379 #quorum 2/2
10633:X 01 Apr 13:46:10.486 # +new-epoch 1
10633:X 01 Apr 13:46:10.486 # +try-failover master redis-test 52.58.69.184 6379
10633:X 01 Apr 13:46:10.488 # +vote-for-leader e3e62e6577aa975f93346dad3d4f8e25833fd8f1 1
10633:X 01 Apr 13:46:10.492 # 07a450af0d2f178410b78ee0f5ae99ce1cd0ac62 voted for e3e62e6577aa975f93346dad3d4f8e25833fd8f1 1
10633:X 01 Apr 13:46:10.492 # e0fe655c59aa3cc32eab1c0858c52418700abe79 voted for e3e62e6577aa975f93346dad3d4f8e25833fd8f1 1
10633:X 01 Apr 13:46:10.559 # +elected-leader master redis-test 52.58.69.184 6379
10633:X 01 Apr 13:46:10.559 # +failover-state-select-slave master redis-test 52.58.69.184 6379
10633:X 01 Apr 13:46:10.611 # +selected-slave slave 52.29.101.118:6379 52.29.101.118 6379 @ redis-test 52.58.69.184 6379
10633:X 01 Apr 13:46:10.612 * +failover-state-send-slaveof-noone slave 52.29.101.118:6379 52.29.101.118 6379 @ redis-test 52.58.69.184 6379
10633:X 01 Apr 13:46:10.664 * +failover-state-wait-promotion slave 52.29.101.118:6379 52.29.101.118 6379 @ redis-test 52.58.69.184 6379
10633:X 01 Apr 13:46:11.498 # +promoted-slave slave 52.29.101.118:6379 52.29.101.118 6379 @ redis-test 52.58.69.184 6379
10633:X 01 Apr 13:46:11.498 # +failover-state-reconf-slaves master redis-test 52.58.69.184 6379
10633:X 01 Apr 13:46:11.557 * +slave-reconf-sent slave 35.159.18.26:6379 35.159.18.26 6379 @ redis-test 52.58.69.184 6379
10633:X 01 Apr 13:46:12.550 * +slave-reconf-inprog slave 35.159.18.26:6379 35.159.18.26 6379 @ redis-test 52.58.69.184 6379
10633:X 01 Apr 13:46:12.550 * +slave-reconf-done slave 35.159.18.26:6379 35.159.18.26 6379 @ redis-test 52.58.69.184 6379
10633:X 01 Apr 13:46:12.632 # -odown master redis-test 52.58.69.184 6379
10633:X 01 Apr 13:46:12.632 # +failover-end master redis-test 52.58.69.184 6379
10633:X 01 Apr 13:46:12.632 # +switch-master redis-test 52.58.69.184 6379 52.29.101.118 6379
10633:X 01 Apr 13:46:12.632 * +slave slave 35.159.18.26:6379 35.159.18.26 6379 @ redis-test 52.29.101.118 6379
10633:X 01 Apr 13:46:12.632 * +slave slave 52.58.69.184:6379 52.58.69.184 6379 @ redis-test 52.29.101.118 6379
10633:X 01 Apr 13:46:18.647 # +sdown slave 52.58.69.184:6379 52.58.69.184 6379 @ redis-test 52.29.101.118 6379

从 Python 检查

>>> sentinel.discover_master('redis-test')
('52.29.101.118', 6379)

主服务器已更改 – 52.29.101.118 – 这是 redis-1 主机。

redis-1 检查状态

admin@redis-1:~$ redis-cli -a foobared info replication

复制角色:主服务器 connected_slaves:1 slave0:ip=35.159.18.26,port=6379,state=online,offset=76847,lag=0 ...

检查 redis-0 主机上的 Redis 节点状态 – 它现在必须成为从服务器

root@redis-0:/home/admin# redis-cli -a foobared info replication
Replication
role:slave
...

并尝试使用我们之前创建的同一个 master 对象在 redis-0 主机上从 Python 添加一个新密钥

>>> master.set('test-key2', 'test-value2')
True

Check

admin@redis-2:~$ redis-cli -a foobared get test-key2
"test-value2"

完成。

© . All rights reserved.