文章目录
一、Redis-Hash类型
hash是一个键值对集合。
hash是一个string类型的field和value的映射表,hash特别适合存储对象。
1.hset/hget/hmset/hmget/hgetall/hdel
意义分别是:
设值/取值/设值多个值/取多个值/取全部值/删除值。
测试如下:
127.0.0.1:6379> keys *
1) "l3"
2) "name"
3) "age"
4) "data"
5) "l4"
6) "proxies"
7) "first"
8) "l1"
9) "l2"
10) "num"
127.0.0.1:6379> hset user id 1
(integer) 1
127.0.0.1:6379> hget user id
"1"
127.0.0.1:6379> hset user name corley
(integer) 1
127.0.0.1:6379> hget user name
"corley"
127.0.0.1:6379> hset user id 2
(integer) 0
127.0.0.1:6379> hget user id
"2"
127.0.0.1:6379> hgetall user
1) "id"
2) "2"
3) "name"
4) "corley"
127.0.0.1:6379> hmset users id 1 name corley sex 1
OK
127.0.0.1:6379> hmget users id name sex
1) "1"
2) "corley"
3) "1"
127.0.0.1:6379> hgetall users
1) "id"
2) "1"
3) "name"
4) "corley"
5) "sex"
6) "1"
127.0.0.1:6379> hdel user id
(integer) 1
127.0.0.1:6379> hgetall user
1) "name"
2) "corley"
127.0.0.1:6379> hdel user name
(integer) 1
127.0.0.1:6379> hgetall user
(empty list or set)
get *
会发现之前的值都还在,这是Redis使用持久化技术将数据保存到了本地磁盘,查看Redis目录,可以看到有一个文件dump.rdb,就是用于保存数据的。
键可以重复,重复时会覆盖,但是在使用时应该尽量避免使用重复的键。
2.hlen
求哈希长度。
测试如下:
127.0.0.1:6379> type users
hash
127.0.0.1:6379> hlen users
(integer) 3
3.hexists key
判断在key里面的某个值是否存在,存在返回1 ,不存在返回0。
测试如下:
127.0.0.1:6379> hexists users id
(integer) 1
127.0.0.1:6379> hexists users height
(integer) 0
4.hkeys/hvals
列举出所有的key和value。
测试如下:
127.0.0.1:6379> hkeys users
1) "id"
2) "name"
3) "sex"
127.0.0.1:6379> hvals users
1) "1"
2) "corley"
3) "1"
二、Redis-Set类型
set是string类型的无序集合。
Set中不存在不重复的值,和普通的集合一样。
1.sadd/smembers/sismember
表示添加/查看集合/查看是否存在。
举例:
sadd set01 1 2 2 3 3 去掉重复添加
smembers set01 得到set01的所有元素
sismember set01 1 如果存在返回1,不存在返回0扫描二维码关注公众号,回复: 10190937 查看本文章
测试如下:
127.0.0.1:6379> sadd se 1 2 2 3 3 4
(integer) 4
127.0.0.1:6379> smembers se
1) "1"
2) "2"
3) "3"
4) "4"
127.0.0.1:6379> sismember se 2
(integer) 1
127.0.0.1:6379> sismember se 5
(integer) 0
2.scard
获取集合里面的元素个数。
测试如下:
127.0.0.1:6379> scard se
(integer) 4
3.srem key value
删除集合中元素。
测试如下:
127.0.0.1:6379> srem se 3
(integer) 1
127.0.0.1:6379> smembers se
1) "1"
2) "2"
3) "4"
127.0.0.1:6379> srem se 5
(integer) 0
4.srandmember key
随机返回数。
测试如下:
127.0.0.1:6379> srandmember se
"1"
127.0.0.1:6379> srandmember se
"2"
127.0.0.1:6379> srandmember se
"4"
127.0.0.1:6379> srandmember se
"2"
127.0.0.1:6379> srandmember se
"2"
127.0.0.1:6379> srandmember se
"1"
127.0.0.1:6379> smembers se
1) "1"
2) "2"
3) "4"
5.spop key
随机弹出元素。
测试如下:
127.0.0.1:6379> spop se
"2"
127.0.0.1:6379> spop se
"4"
127.0.0.1:6379> spop se
"1"
127.0.0.1:6379> sadd se1 1 7 5 3 2 4 7
(integer) 6
127.0.0.1:6379> spop se1
"7"
127.0.0.1:6379> spop se1
"3"
127.0.0.1:6379> spop se1
"2"
127.0.0.1:6379> smembers se1
1) "1"
2) "4"
3) "5"
6.smove key1 key2
移动元素。
举例说明:
smove set01 set03 2 将set01中的2 移动到set03中
测试如下:
127.0.0.1:6379> smove se1 se 1
(integer) 1
127.0.0.1:6379> smembers se
1) "1"
7.集合操作
与数学中的集合操作类似,其中:
- SDIFF
差集操作 - SINTER
交集操作 - SUNION
并集操作
测试如下:
127.0.0.1:6379> sadd set01 1 2 3 4 5
(integer) 5
127.0.0.1:6379> sadd set02 1 2 3 a b
(integer) 5
127.0.0.1:6379> SDIFF set01 set02
1) "4"
2) "5"
127.0.0.1:6379> SINTER set01 set02
1) "1"
2) "2"
3) "3"
127.0.0.1:6379> SUNION set01 set02
1) "4"
2) "a"
3) "1"
4) "2"
5) "3"
6) "5"
7) "b"
三、Redis-Zset类型
ZSet是Redis中的有序集合类型。
1.zadd/zrange
设置和根据范围获取值。
测试如下:
127.0.0.1:6379> zadd ze 60 v1 70 v2 80 v3 90 v4 100 v5
(integer) 5
127.0.0.1:6379> zrange ze 0 -1
1) "v1"
2) "v2"
3) "v3"
4) "v4"
5) "v5"
127.0.0.1:6379> zadd ze1 60 v1 70 v2 80 v3 100 v4 90 v5
(integer) 5
127.0.0.1:6379> zrange ze1 0 -1
1) "v1"
2) "v2"
3) "v3"
4) "v5"
5) "v4"
127.0.0.1:6379> zadd ze2 60 v1 70 v2 80 v3 90 v4 90 v5
(integer) 5
127.0.0.1:6379> zrange ze2 0 -1
1) "v1"
2) "v2"
3) "v3"
4) "v4"
5) "v5"
127.0.0.1:6379> zadd ze3 name v1 age v2 80 v3 90 v4 90 v5
(error) ERR value is not a valid float
127.0.0.1:6379> zadd ze4 60 v1 70 v2 80 v1 90 v4 90 v5
(integer) 4
127.0.0.1:6379> zrange ze4 0 -1 withscores
1) "v2"
2) "70"
3) "v1"
4) "80"
5) "v4"
6) "90"
7) "v5"
8) "90"
显然,zset的值只能是数值型(浮点数),如果是字符串会报错;
如果键相同,后边对应的值会覆盖前面对应的值。
2.zrangebyscore key start end
根据开始结束来取值;
结束不包括用 (;
limit限制从指定索引开始获取指定条数据。
测试如下:
127.0.0.1:6379> zrangebyscore ze 60 80
1) "v1"
2) "v2"
3) "v3"
127.0.0.1:6379> zrangebyscore ze 60 (80
1) "v1"
2) "v2"
127.0.0.1:6379> zrangebyscore ze 60 80 limit 1 2
1) "v2"
2) "v3"
127.0.0.1:6379> zrangebyscore ze 60 80 limit 1 2
1) "v2"
2) "v3"
127.0.0.1:6379> zrangebyscore ze 60 80 limit 0 2
1) "v1"
2) "v2"
3.zrem key
删除元素。
测试如下:
127.0.0.1:6379> zrem ze v1
(integer) 1
127.0.0.1:6379> zrange ze 0 -1
1) "v2"
2) "v3"
3) "v4"
4) "v5"
4.zcard/zcount/zrank
获取数据总数/指定范围的数据个数/返回数据对应下标。
测试如下:
127.0.0.1:6379> zcard ze
(integer) 4
127.0.0.1:6379> zcount ze 70 90
(integer) 3
127.0.0.1:6379> zrank ze v4
(integer) 2
四、Python操作Redis
1.Python中redis的安装和连接
如果未安装redis库,需要先通过命令安装:
pip install redis
连接方式如下 :
r = redis.StrictRedis(host='localhost',port=6379,db=0)
2.Python操作Redis-String
简单测试:
import redis
r = redis.StrictRedis(host='localhost', port=6379, db=0) # 与redis.Redis()效果相同
print(r)
打印
Redis<ConnectionPool<Connection<host=localhost,port=6379,db=0>>>
显然,r是一个redis对象。
封装类操作:
import redis
class StringRedis(object):
def __init__(self):
self.r = redis.StrictRedis() # 因连接参数为默认,所以可以不带参数
def string_set(self, key, item):
'''字符串设置值'''
res = self.r.set(key, item) # 返回布尔值
print(res)
def string_get(self, key):
'''字符串取值'''
res = self.r.get(key) # 返回字节型数据
return res
if __name__ == '__main__':
s = StringRedis()
s.string_set('user', 'corley')
res = s.string_get('user')
print(type(res), res)
打印
True
<class 'bytes'> b'corley'
进一步完善操作:
import redis
class StringRedis(object):
def __init__(self):
self.r = redis.StrictRedis() # 因连接参数为默认,所以可以不带参数
def string_set(self, key, item):
'''字符串设置值'''
res = self.r.set(key, item) # 返回布尔值
print(res)
def string_get(self, key):
'''字符串取值'''
res = self.r.get(key) # 返回字节型数据
return res
def string_mset(self, items):
'''字符串设置多个值'''
if isinstance(items, dict):
res = self.r.mset(items) # 返回布尔值
print(res)
def string_mget(self, keys):
'''字符串取多个值'''
if isinstance(keys, list):
return self.r.mget(keys)
def string_del(self, key):
'''删除值'''
if self.r.exists(key):
self.r.delete(key)
else:
return '%s Not Found' % key
if __name__ == '__main__':
s = StringRedis()
s.string_set('user', 'corley')
res1 = s.string_get('user')
print(type(res1), res1)
d = {
'age':18,
'sex':1
}
s.string_mset(d)
res2 = s.string_mget(['user', 'age', 'sex'])
print(type(res2), res2)
res3 = s.string_del('user')
res4 = s.string_del('name')
print(res3, res4)
打印
True
<class 'bytes'> b'corley'
True
<class 'list'> [b'corley', b'18', b'1']
None name Not Found
3.Python操作Redis-List
import redis
class ListRedis(object):
def __init__(self):
self.r = redis.StrictRedis()
def list_lpush(self, key, item):
'''列表设置值'''
res = self.r.lpush(key, item) # 返回布尔值
print(res)
def list_lpop(self, list):
'''列表弹出值'''
res = self.r.lpop(list) # 返回字节型数据
return res
if __name__ == '__main__':
l = ListRedis()
l.list_lpush('li', 1)
l.list_lpop('li')
打印
1
Python中List添加值一次只能添加一个,如有多个,可以使用循环。
再次测试:
import redis
class ListRedis(object):
def __init__(self):
self.r = redis.StrictRedis()
def test_push(self):
res = self.r.lpush('test','1')
res = self.r.rpush('test','2')
res = self.r.rpush('test','3')
def test_pop(self):
res = self.r.lpop('test')
print(res)
res = self.r.rpop('test')
print(res)
def test_range(self):
res = self.r.lrange('test',0,-1)
print(res)
if __name__ == '__main__':
l = ListRedis()
l.test_push()
l.test_range()
l.test_pop()
打印
[b'1', b'2', b'3']
b'1'
b'3'
4.Python操作Redis-Set
简单操作示例如下:
import redis
class SetRedis(object):
def __init__(self):
self.r = redis.StrictRedis()
def test_sadd(self):
res = self.r.sadd('set1','1','2')
def test_del(self):
res = self.r.srem('set1',1)
def test_pop(self):
res = self.r.spop('set1')
def test_members(self, key):
res = self.r.smembers(key)
print(res)
if __name__ == '__main__':
s = SetRedis()
s.test_sadd()
s.test_members('set1')
s.test_del()
s.test_members('set1')
s.test_pop()
s.test_members('set1')
打印
{b'2', b'1'}
{b'2'}
set()
5.Python操作Redis-Hash
用Python操作Redis-Hash示例如下:
import redis
class HashRedis(object):
def __init__(self):
self.r = redis.StrictRedis()
def test_hset(self):
dic = {
'id': 1,
'name': 'huawei'
}
res = self.r.hmset('mobile', dic)
def test_hgetall(self):
res = self.r.hgetall('mobile')
print(res)
def test_hexists(self):
res = self.r.hexists('mobile', 'id')
print(res)
if __name__ == '__main__':
h = HashRedis()
h.test_hset()
h.test_hgetall()
h.test_hexists()
打印
{b'id': b'1', b'name': b'huawei'}
True
五、Redis主从配置
1.主从概念
在实际过程中,缓存可能因为内存占用更多或其他不可预料的因素而崩溃,这样会使得用户直接访问数据库,从而导致主数据据库的访问压力大大增加,所以为了使缓存不易发生数据库崩溃,应该对缓存建立主从配置,从而提高系统的容灾性能。
Redis主从配置特性如下:
- ⼀个master可以拥有多个slave,⼀个slave⼜可以拥有多个slave,如此下去,形成了强⼤的多级服务器集群架构
- master用来写数据,slave用来读数据,读数据比写数据多得多(据统计,网站的读写比率是10:1)
- 通过主从配置可以实现读写分离
- master和slave都是一个redis实例(redis服务)
示意如下:
2.主从配置过程
以下相关操作均是在Linux(Kali)进行的。
可以在Redis配置文件中设置守护线程参数daemonize为yes,以便后面更方便地开启Redis服务,如下:
配置主机和开启服务
- 修改redis.conf配置文件
bind 0.0.0.0 # 或者改成本机IP
- 开启主机服务
src/redis-server redis.conf
配置从机和开启服务
- 复制redis.conf配置文件
cp redis.conf slave.conf
- 修改slave.conf文件
有3处修改的地方:
bind 192.168.186.132(主机IP,通过ifconfig名获取)
…
port 6378(从机端口)
…
replicaof 192. 168.186.132(主机IP) 6379(主机端口) # 旧版本Redis中为slaveof
在配置文件中位置示意如下:
- 开启从机服务
src/redis-server slave.conf
主从数据操作测试
- 连接主从客户端
src/redis-cli -p 6379
src/redis-cli -h 192.168.186.132 -p 6378
- 读写数据
在主机上写数据:
set name corley
在从机上读数据:
get name
具体演示过程如下:
可以看出,主机才有写权限,从机只能读。