redis初探

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
# import redis
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)
# 输出:('192.168.196.132', 6379)


# 获取从服务器地址
slave = sentinel.discover_slaves('mymaster')
print(slave)
# 输出:[('192.168.196.129', 6379)]


# 获取主服务器进行写入
master = sentinel.master_for('mymaster', socket_timeout=0.5, password='newpwd', db=0)
w_ret = master.set('foo', 'bar')
# 输出:True

# 获取从服务器进行读取(默认是round-roubin,随机从多个slave服务中读取数据)
slave = sentinel.slave_for('mymaster', socket_timeout=0.5, password='newpwd', db=0)
r_ret = slave.get('foo')
print(r_ret)
# 输出:bar

封装工具类方法

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():
# redis info
sentinel_list = [('192.168.196.129', 26379),('192.168.196.132', 26379)]
password = 'newpwd'
db = 0
service_name = 'mymaster'

# create redis link
rsh = redisSentinelHelper(sentinel_list=sentinel_list,password=password,service_name=service_name,db=db)

# test set key : key1 test-insert-key1
rsh.set_key('key1','test-insert-key1')

# get 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():
# redis info
sentinel_list = [('192.168.196.129', 26379),('192.168.196.132', 26379)]
password = 'newpwd'
db = 0
service_name = 'mymaster'

# create redis link
rsh = redisSentinelHelper(sentinel_list=sentinel_list,password=password,service_name=service_name,db=db)

# test set key : key1 test-insert-key1
# rsh.set_key('key1','test-insert-key1')

# get key1
# print(rsh.get_key('key1'))

# loop set key
for i in range(0,1000000):
rsh.set_key('key' + str(i), i)
print(rsh.get_key('key' + str(i)))

if __name__ == '__main__':
_test()

redis缓存
http://example.com/2021/07/14/2021-07-14-redis缓存/
作者
NSX
发布于
2021年7月14日
许可协议