1、安装
1.1 安装
sudo apt-get install redis-server
1.2服务端启动
sudo /etc/init.d/redis-server status | start | stop | restart
1.3客户端连接
redis-cli -h IP地址 -p 端口
redis-cli # 默认连接本机的6379端口
127.0.0.1:6379>ping
PONG
2、常用命令
# 切换库
select number
# 查看键
keys *
# 键类型
TYPE key
# 键是否存在
exists key
# 删除键
del key
# 键重命名
rename key newkey
# 返回旧值并设置新值(如果键不存在,就创建并赋值)
getset key value
# 清除当前库中所有数据(慎用)
flushdb
# 清除所有库中所有数据(慎用)
flushall
1. 设置一个key-value
set key value
2. 获取key的值
get key
3. key不存在时再进行设置(nx)
set key value nx
4. 设置过期时间(ex)
set key value ex seconds
5. 同时设置多个key-value
mset key1 value1 key2 value2 key3 value3
6. 同时获取多个key-value
mget key1 key2 key3
3、整数操作
INCRBY key 步长
DECRBY key 步长
INCR key : +1操作
DECR key : -1操作
# 应用场景: 抖音上有人关注你了,是不是可以用INCR呢,如果取消关注了是不是可以用DECR
# 浮点数操作: 先转为数字类型,然后再进行相加减,不能使用append
incrbyfloat key step
4、列表
4、列表常用操作
# 增
1、LPUSH key value1 value2
2、RPUSH key value1 value2
3、RPOPLPUSH source destination
4、LINSERT key after|before value newvalue
# 查
5、LRANGE key start stop
6、LLEN key
# 删
7、LPOP key
8、RPOP key
9、BLPOP key timeout
10、BRPOP key timeout
11、LREM key count value
12、LTRIM key start stop
# 改
13、LSET key index newvalue
4.2 python使用
import redis
r = redis.Redis(host='192.168.43.49',port=6379,db=0)
# ['mysql','redis']
r.lpush('pylist','redis','mysql')
# ['mysql','redis','django','spider']
r.rpush('pylist','django','spider')
# ['mysql','redis','django','spider','AI']
r.linsert('pylist','after','spider','AI')
# 5
print(r.llen('pylist'))
# ['redis','django','spider']
r.lpop('pylist')
r.rpop('pylist')
# ['redis','django','spider']
print(r.lrange('pylist',0,-1))
# ['redis','spider']
r.lrem('pylist',0,'django')
# 返回True,['redis']
r.ltrim('pylist',0,0)
# 返回True,['spiderman']
r.lset('pylist',0,'spiderman')
r.delete('pylist')
5、字符串代码示例
import redis
r = redis.Redis(host='192.168.43.49',port=6379,db=0)
r.set('mystring','python')
# b'python'
print(r.get('mystring'))
# False
print(r.setnx('mystring','socket'))
# mset:参数为字典
r.mset({'mystring2':'mysql','mystring3':'mongodb'})
# mget:结果为一个列表
print(r.mget('mystring','mystring2','mystring3'))
# mystring长度:6
print(r.strlen('mystring'))
# 数字类型操作
r.set('number',10)
r.incrby('number',5)
r.decrby('number',5)
r.incr('number')
r.decr('number')
r.incrbyfloat('number',6.66)
r.incrbyfloat('number',-6.66)
# b'10'
print(r.get('number'))
6、Hash散列
6.1基本命令操作
HSET key field value
HSETNX key field value
HMSET key field value field value
HLEN key
HEXISTS key field
HGET key field
HMGET key field filed
HGETALL key
HKEYS key
HVALS key
HDEL key field
HINCRBY key filed increment
HINCRBYFLOAT key field increment
6.2phthon基本方法
hset(name, key, value)
hget(name, key)
hmset(name, mapping)
hmget(name, keys)
hgetall(name)
hkeys(name)
hdel(name, *keys)
7、集合
7.1特点
1、无序、去重
2、元素是字符串类型
3、最多包含2^32-1个元素
7.2基本命令
SADD key member1 member2
SMEMBERS key
SREM key member1 member2
SISMEMBER key member
SRANDOMMEMBER key [count]
SCARD key
SMOVE source destination member
SDIFF key1 key2
SDIFFSTORE destination key1 key2
SINTER key1 key2
SINTERSTORE destination key1 key2
SUNION key1 key2
SUNIONSTORE destination key1 key2
7.3 python操作set
sadd(name,values)
r.sadd("set_name","tom")
r.sadd("set_name","tom","jim")
smembers(name)
scard(name)
r.scard("set_name")
sismember(name, value)
spop(name)
srem(name, value)
r.srem("set_name", "tom")
sinter(keys, *args)
r.sadd("set_name","a","b")
r.sadd("set_name1","b","c")
r.sadd("set_name2","b","c","d")
print(r.sinter("set_name","set_name1","set_name2"))
sunion(keys, *args)
r.sunion("set_name","set_name1","set_name2")
8、有序集合
8.1python操作sorted set
import redis
r = redis.Redis(host='192.168.43.49',port=6379,password='123456',db=0)
# 注意第二个参数为字典
r.zadd('salary',{'tom':6000,'jim':8000,'jack':12000})
# 结果为列表中存放元组[(),(),()]
print(r.zrange('salary',0,-1,withscores=True))
print(r.zrevrange('salary',0,-1,withscores=True))
# start:起始值,num:显示条数
print(r.zrangebyscore('salary',6000,12000,start=1,num=2,withscores=True))
# 删除
r.zrem('salary','tom')
print(r.zrange('salary',0,-1,withscores=True))
# 增加分值
r.zincrby('salary',5000,'jack')
print(r.zrange('salary',0,-1,withscores=True))
# 返回元素排名
print(r.zrank('salary','jack'))
print(r.zrevrank('salary','jack'))
# 删除指定区间内的元素
r.zremrangebyscore('salary',6000,8000)
print(r.zrange('salary',0,-1,withscores=True))
# 统计元素个数
print(r.zcard('salary'))
# 返回指定范围内元素个数
print(r.zcount('salary',6000,20000))
# 并集
r.zadd('salary2',{'jack':17000,'lucy':8000})
r.zunionstore('salary3',('salary','salary2'),aggregate='max')
print(r.zrange('salary3',0,-1,withscores=True))
# 交集
r.zinterstore('salary4',('salary','salary2'),aggregate='max')
print(r.zrange('salary4',0,-1,withscores=True))
9、数据持久化
9.1 服务器执行客户端发送的SAVE或者BGSAVE命令
127.0.0.1:6379> SAVE
OK
1、执行SAVE命令过程中,redis服务器将被阻塞,无法处理客户端发送的命令请求,在SAVE命令执行完毕后,服务器才会重新开始处理客户端发送的命令请求
2、如果RDB文件已经存在,那么服务器将自动使用新的RDB文件代替旧的RDB文件
127.0.0.1:6379> BGSAVE
Background saving started
1、客户端 发送 BGSAVE 给服务器
2、服务器马上返回 Background saving started 给客户端
3、服务器 fork() 子进程做这件事情
4、服务器继续提供服务
5、子进程创建完RDB文件后再告知Redis服务器
/etc/redis/redis.conf
263行: dir /var/lib/redis
253行: dbfilename dump.rdb
9.1 设置配置文件条件满足时自动保存(使用最多)
redis>save 300 10
表示如果距离上一次创建RDB文件已经过去了300秒,并且服务器的所有数据库总共已经发生了不少于10次修改,那么自动执行BGSAVE命令
redis>save 60 10000
表示如果距离上一次创建rdb文件已经过去60秒,并且服务器所有数据库总共已经发生了不少于10000次修改,那么执行bgsave命令
218行: save 900 1
219行: save 300 10
220行: save 60 10000
1、只要三个条件中的任意一个被满足时,服务器就会自动执行BGSAVE
2、每次创建RDB文件之后,服务器为实现自动持久化而设置的时间计数器和次数计数器就会被清零,并重新开始计数,所以多个保存条件的效果不会叠加
9.3 数据持久化分类之 - AOF(AppendOnlyFile,默认未开启)
9.3.1特点
1、存储的是命令,而不是真实数据
2、默认不开启
1、/etc/redis/redis.conf
672行: appendonly yes
676行: appendfilename "appendonly.aof"
2、重启服务
sudo /etc/init.d/redis-server restart
9.3.2RDB缺点
1、创建RDB文件需要将服务器所有的数据库的数据都保存起来,这是一个非常消耗资源和时间的操作,所以服务器需要隔一段时间才创建一个新的RDB文件,也就是说,创建RDB文件不能执行的过于频繁,否则会严重影响服务器的性能
2、可能丢失数据
9.3.3AOF持久化原理及优点**
1、每当有修改数据库的命令被执行时,服务器就会将执行的命令写入到AOF文件的末尾
2、因为AOF文件里面存储了服务器执行过的所有数据库修改的命令,所以给定一个AOF文件,服务器只要重新执行一遍AOF文件里面包含的所有命令,就可以达到还原数据库的目的
用户可以根据自己的需要对AOF持久化进行调整,让Redis在遭遇意外停机时不丢失任何数据,或者只丢失一秒钟的数据,这比RDB持久化丢失的数据要少的多
10、主从复制
10.1 定义
1、一个Redis服务可以有多个该服务的复制品,这个Redis服务成为master,其他复制品成为slaves
2、master会一直将自己的数据更新同步给slaves,保持主从同步
3、只有master可以执行写命令,slave只能执行读命令
10.2实现方式
10.2.1 方式一(命令行实现1)
redis-server --slaveof
redis-server --port 6300 --slaveof 127.0.0.1 6379
redis-cli -p 6300
127.0.0.1:6300> keys *
127.0.0.1:6380> set mykey 123
(error) READONLY You can't write against a read only slave.
127.0.0.1:6380>
10.2.2 方式二(修改配置文件)
vi redis_6300.conf
slaveof 127.0.0.1 6379
port 6300
redis-server redis_6300.conf
redis-cli -p 6300
127.0.0.1:6300> hset user:1 username guods
(error) READONLY You can't write against a read only slave.
问题总结
1、一个Master可以有多个Slaves
2、Slave下线,只是读请求的处理性能下降
3、Master下线,写请求无法执行
4、其中一台Slave使用SLAVEOF no one命令成为Master,其他Slaves执行SLAVEOF命令指向这个新的Master,从它这里同步数据
redis分布式锁
def test(request):
import redis
pool = redis.ConnectionPool(host='localhost', port=6379, db=0)
r = redis.Redis(connection_pool=pool)
while True:
try:
with r.lock('guoxiaonao', blocking_timeout=3) as lock:
u = UserProfile.objects.get(username='guoxiaonao')
u.score += 1
u.save()
break
except Exception as e:
print('lock is failed')
return HttpResponse('HI HI HI')