Redis 简介
REmote DIctionary Server(Redis) 是一个由 Salvatore Sanfilippo 写的 key-value 存储系统,是跨平台的非关系型数据库。
Redis 与其他 key - value 缓存产品有以下三个特点:
- Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。
- Redis不仅仅支持简单的key-value类型的数据,同时还提供字符串(String)、哈希(Hash)、列表(list)、集合(sets)和有序集合(sorted sets)等数据结构的存储。
- Redis支持数据的备份,即master-slave模式的数据备份。
Redis 优势
- 性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。
- 丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。
- 原子 – Redis的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过MULTI和EXEC指令包起来。
- 丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。
安装 redis 模块
Python 要使用 redis,需要先安装 redis 模块:
1 2 3
| sudo pip3 install redis 或 sudo python setup.py install
|
测试是否安装成功:
1 2 3 4 5 6
| >>> import redis >>> r = redis.StrictRedis(host='localhost', port=6379, db=0) >>> r.set('foo', 'bar') True >>> r.get('foo') 'bar'
|
redis 提供两个类 Redis 和 StrictRedis, StrictRedis 用于实现大部分官方的命令,Redis 是 StrictRedis 的子类,用于向后兼用旧版本。
redis 取出的结果默认是字节,我们可以设定 decode_responses=True 改成字符串。
实例
1 2 3 4 5 6 7
| import redis # 导入redis 模块
r = redis.Redis(host='localhost', port=6379, decode_responses=True) r.set('name', 'runoob') # 设置 name 对应的值 print(r['name']) print(r.get('name')) # 取出键 name 对应的值 print(type(r.get('name'))) # 查看类型
|
输出结果为:
1 2 3
| runoob runoob <class 'str'>
|
连接redis sentinel集群
https://blog.csdn.net/u012887259/article/details/102425691
示例代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| from redis.sentinel import Sentinel """ 1、通过访问Sentinel服务的方式,获取redis的master、slave节点信息 2、向master redis写入数据 3、从slave redis读取数据 """
sentinel = Sentinel([('192.168.196.129', 26379), ('192.168.196.132', 26379) ], socket_timeout=0.5)
master = sentinel.discover_master('mymaster') print(master)
slave = sentinel.discover_slaves('mymaster') print(slave)
master = sentinel.master_for('mymaster', socket_timeout=0.5, password='newpwd', db=0) w_ret = master.set('foo', 'bar')
slave = sentinel.slave_for('mymaster', socket_timeout=0.5, password='newpwd', db=0) r_ret = slave.get('foo') print(r_ret)
|
封装工具类方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| from redis.sentinel import Sentinel class redisSentinelHelper(): def __init__(self,sentinel_list,service_name,password,db): self.sentinel = Sentinel(sentinel_list,socket_timeout=0.5) self.service_name = service_name self.password = password self.db = db def get_master_redis(self): return self.sentinel.discover_master(self.service_name) def get_slave_redis(self): return self.sentinel.discover_slaves(self.service_name) def set_key(self,key,value): master = self.sentinel.master_for( service_name=self.service_name, socket_timeout=0.5, password=self.password, db=self.db ) return master.set(key,value) def get_key(self,key): slave = self.sentinel.slave_for( service_name=self.service_name, socket_timeout=0.5, password=self.password, db=self.db ) return slave.get(key) def _test(): sentinel_list = [('192.168.196.129', 26379),('192.168.196.132', 26379)] password = 'newpwd' db = 0 service_name = 'mymaster' rsh = redisSentinelHelper(sentinel_list=sentinel_list,password=password,service_name=service_name,db=db) rsh.set_key('key1','test-insert-key1') print(rsh.get_key('key1')) if __name__ == '__main__': _test()
|
运行如下:
1 2
| D:\Python37\python3.exe D:/pythonProject/redis-test/test7.py b'test-insert-key1'
|
其中,我没有把设置master节点写在初始化,而是在set key操作的时候才创建连接,主要是后续想要测试master节点变化的情况下,写入能够继续。
当然这样的话性能肯定不会很好,有很多可以根据实际情况修改的地方。
测试:当master节点切换,能否自动连续写入
当然,在sentinel执行master切点切换的过程,肯定会有些丢失,但是主要是要看切换之后,是否可以自动继续写入数据。
首先编写一个循环写入的示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| from redis.sentinel import Sentinel
class redisSentinelHelper(): def __init__(self,sentinel_list,service_name,password,db): self.sentinel = Sentinel(sentinel_list,socket_timeout=0.5) self.service_name = service_name self.password = password self.db = db
def get_master_redis(self): return self.sentinel.discover_master(self.service_name) def get_slave_redis(self): return self.sentinel.discover_slaves(self.service_name) def set_key(self,key,value): master = self.sentinel.master_for( service_name=self.service_name, socket_timeout=0.5, password=self.password, db=self.db ) return master.set(key,value) def get_key(self,key): slave = self.sentinel.slave_for( service_name=self.service_name, socket_timeout=0.5, password=self.password, db=self.db ) return slave.get(key)
def _test(): sentinel_list = [('192.168.196.129', 26379),('192.168.196.132', 26379)] password = 'newpwd' db = 0 service_name = 'mymaster'
rsh = redisSentinelHelper(sentinel_list=sentinel_list,password=password,service_name=service_name,db=db) for i in range(0,1000000): rsh.set_key('key' + str(i), i) print(rsh.get_key('key' + str(i)))
if __name__ == '__main__': _test()
|