Redis
特点:
1.开源,C语言编写,基于内存、支持持久化
2.数据类型包含:string hashes lists sets sorted sets
3.单进程单线程、非关系型的KV型数据库
功能:
持久化(数据备份至磁盘)
过期键功能(节约内存)
事务功能(只具备简单事务)
主从复制(官方提供主从搭建方案)
Sentinel哨兵(自动故障转移)
应用场景:缓存、并发计数、排行榜、生产者消费者模型
常用版本: 3.0(里程碑) 3.2 3.4 4.0 5.0
安装&连接
Centos7安装redis
与Ubuntu启动方法不同
www.cnblogs.com/heqiuyong/p/10463334.html
Ubuntu安装redis
安装:sudo apt-get install redis-server
服务器启动/停止/重启/状态:sudo /etc/init.d/redis-server start|stop|restart|status
客户端连接:redis-cli -h IP地址 -p 6379 -a 密码
测试命令: redis-benchmark -q -n 10000
配置文件
路径: /etc/redis/redis.conf(修改前先备份)
后台启动:daemonize no => daemonize yes
密码:requirepass 密码
开启远程连接:注释bind 127.0.0.1 ::1
protected-mode no => protected-mode yes
基础命令
* 命令不区分大小写
select number :选择数据库(redis默认16个数据库,0-15为数据库编号)
info [CPU|...] :查看redis服务情况
key 匹配模式 :查找符合模式的key(正式环境忌用)
type key :当前键的数据类型
exists key :key是否存在
del key :删除key
rename key newkaey :重命名键名
flushdb :清楚当前所在数据库
flushall :清除所有数据库
****************数值操作************************************
incrby key 步长 :key值+步长(数值操作)
decrby key 步长 :key值-步长(数值操作)
incr key :key值+1(数值操作)
decr key :key值-1(数值操作)
****************时限操作************************************
expire key 时间 :附加过期时间(秒)
pexpire key 时间 :附加过期时间(毫秒)
tll key :查询过期时间
persisit key :变为永久
数据类型
字符串(字符串和数字都以字符串存储)
规范:key值不要过长又要保持可读性
set key value nx ex :插入数据(键值对)
nx => not exist 当这个key不存在时,才存入这个key
ex => expire 过期时间,单位s
eg: set a b nx ex 9
get key :取值
strlen key :获取key存储值的长度
getrange key start stop :获取可以存储值的切片
setrange key index value :从索引位置开始用value替换原内容;返回新长度
mset key1 value1 key2 value2... :批量添加
mget key1 key2 key3... :批量获取
数组
概念:元素是字符串 头尾增删快,中间慢 最多2^32-1个元素 索引同python列表
**********************列表操作****************************
lpush key value1 value2 :从列表头部压入
rpush key value1 value2 :从列表尾部压入
lrange key start stop :获取可以存储列表的切片
llen key :获取key存储列表的长度
rpoplpush src dst :从列表src弹出,压入dst
linsert key after|before value newvalue :指定元素 前|后 插入新元素(消耗大)
lpop|rpop key :左弹出,右弹出
blpop|brpop key timeout:左阻塞弹出,右阻塞弹出 timeout为最长阻塞时间(timeout=0为永久阻塞,同一列表服从先来先服务)
lrem key count value :
count>0 从头遍历查找,删除|count|个等于value的元素
count>0 从尾遍历查找,删除|count|个等于value的元素
count=0 删除所有等于value的元素
ltrim key start stop :保留指定范围内元素
lset key index newvalue :设置指定索引的值
lpush [key] [value] # key用“:”隔开,前面部分生成文件夹形式
位图
哈希
特点: 字段小于512个,value不超过64位字节。只能对键进行过期,不能对字段进行过期
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:返回所有键值对
hvals key:返回所有字段的值
hincrby h1 age 2:h1.age的值加2(incr加)
集合
特点:无序,去重,最多包含2^32-1个元素
sadd key value1 value2:增加一个或多个元素,自动去重
smembers key:集合中所有成员
srem key value1 value2:删除一个或多个元素,多余自动忽略
sismember key value:元素是否存在
srandmember key [count]:随机返回集合中指定个数的元素
spop key [count]:随机删除指定个数元素
scard:返回集合中的元素个数
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:并集保持到目标集合中
应用场景:1.社交平台共同好友 2.随机抽奖 3.去重 4.黑/白名单
注意:set中为纯数字是,set结构为有序集合,存在字符串是为无序集合(哈希结构)
有序集合
特点:1.有序,去重 2.每个元素关联一个浮点分数值,并按分值有序排列
zadd key score member:添加一个元素,返回添加成功个数
zrange key start stop:查看指定区间元素
zrevrange key start stop:查看指定元素
zscore key member:查看指定分值
zrank/zrerank key member:查成员的排名(正向/反向)
zrangebyscore key min max [withscores] [limit offset count]
min/max:最小值、最大值区间 (min 表示开区间
zrem key member:删除成员
zincrby key increment:增加减少分值
zremrangebyscore key min max:删除指定区间内元素
zcard key:删除元素个数
zcount key min max:返回指定范围中的元素个数
zunionstore destination 2 key1 key2 [weights 权重值1 权重值2] [aggregate sum|min|max] :求并集 新集合权值为(求和|取最大值|取最小值)
zinterstore destination 2 key1 key2 [weights 权重值1 权重值2] [aggregate sum|min|max] :同并集
删除机制
惰性删除:再查询数据时删除过期数据
定期删除:定期运行删除程序,删除程序逐一遍历数据库,用随机抽样来删除过期数据。当过期数据过多时,删除程序会在限定时间内(25ms)停止
最大内存检查:配置maxmemory 内存超过最大限制时,redis触发淘汰内存。
淘汰机制如下:
volatile-lru:设置了过期时间的内存数据,进行最近最少使用淘汰
volatile-ttl:设置了过期时间的内存数据,进行即将过期淘汰
volatile-random:设置了过期时间的内存数据,进行完全随机淘汰
allkeys-lru:所与的内存数据,进行最近最少使用淘汰
allkey-random:所与的内存数据,进行完全随机淘汰
no-envivtion:禁止大多写入命令
事务
特性:
- 原子性 事务操作不可再分割,要么全成功要么全失败
- 一致性 数据完整性约束,约束包括主键、外键和多种自定义约束。
- 隔离性 事务之间互不打扰
- 持久性 事务一旦成功提交,数据库永久发生改变
Redis:弱事务型数据库
- 具备隔离性,Redis单线程执行
- 不保证原子性,事务中一个命令失败,其他命令照常执行
操作
multi :开启事务
命令1
命令2
...
exec :提交事务
discard :取消事务
常见错误
如:set num 10 lpop num
则 set成功执行 lpop执行失败
pipeline流水线
批量处理redis命令。客户端将多个命令打包再发送,减少redis请求次数
注意: 如果下一个命令需要上一个命令的执行结果才可执行,则无法使用该技术
使用方法
pool = redis.ConnectionPool
r = redis.Redis(connection_pool=pool)
pipe = r.pipeline()
pip.set()
pip.execute()
# python操作事务,需要依赖流水线事务
with r.pipeline(transaction=true) as pipe
pipe.multi()
pipe.incr('books')
pipe.incr('books')
values = pipe.execute()
乐观锁---watch
事务过程中对指定key进行监听,命令提交时,若监听的key值未改变,则提交成功,否则失败。
> watch
> multi
> incr books
> exec
# python中使用乐观锁
try:
pipe.watch(key)
pipe.multi()
pipe.set()
pipe.execute()
except redis.WatchError:
print('error')
持久化
RDB
基础概念:
- 保持真实数据
- 修改文件名及目录:打开redis/redis.conf
修改 263行 253行 dir dbfilename
触发持久化
> SAVE
# 特点:
1. 执行SAVE命令时,redis服务被阻塞,直到命令结束
2. 如果RDB文件已存在,则服务器自动替换
> BGSAVE
# 执行过程:
1. 客户端发生BGSAVE给服务器
2. 服务器fork()子进程执行任务
3. 服务器继续提供服务
4. 子进程创建完RDB文件再告知Redis服务器
SAVE vs. BGSAVE
1. save比bgsave快
2. 可通过查看redis-server.log日志文件,来查看redis的持久化过程
配置文件
218行 save 900 1 # 900秒内修改1次以上,则执行bgsave
219行 save 300 10 # 300秒内修改10次以上,则执行bgsave
* 注意:每次创建RDB文件都会 清空 时间计数器和次数计数器
异常关闭无法触发RDB操作
特色说明:不能过于频繁执行创建RDB操作,可能丢失部分数据
AOF
基础概念
- 存储的是命令
- 默认不开启
# 开启方式
redis.conf
672行 appendonly yes
676行 appendfilename “appendonly.aof”
# 重启服务
redis-server restart
相关配置
# 配置相关策略
701行 alwarys 每一条命令都写入硬盘里
702行 everysec(默认) 每一秒将缓冲区命令写进硬盘里
703行 no 写入硬盘时机由系统控制
AOF重写
为了控制AOF文件的大小,redis提供了AOF重写功能,可对原有文件进行简化,且重写期间我服务器正常处理请求
# 触发
1. 客户端发送重写AOF命令
> BGREWRITEAOF
2. 修改配置文件,使服务器自动执行重写AOF
auto-aof-rewrite-percentage 100 AOF文件大一倍时重写
auto-aof-rewrite-min-size 64mb AOF文件64M时重写
高可用方案 主从复制+哨兵
主从复制
概念
- 一个服务有多个该服务复制品,redis服务称为master,复制品称为slaves
- master一直同步数据给slaves
- 只有master可以写,slave只能读
- 作用:分担读压力。客户端可以连接slaves执行读请求,减低master的读压力
实现方式--命令行
# 命令
redis-server --slaveof <master-ip> <master-port> --masterauth <master-password>
# 从服务端
redis-server --port 6300 --slaveof 127.0.0.1 6379
# 从客户端
redis -p 6300
# 成为谁的从服务
> slaveof IP PORT
# 自立为王
> slaveof no one
实现方式--配置文件
# 每个redis服务,都有1个对应的配置文件
# 修改配置文件
vi redis_6300.conf
slaveof 127.0.0.1 6379
port 6300
# 启动redis服务
redis-server redis_6300.conf
# 客户端连接
redis-cli -p 6300
哨兵
概念
原理:哨兵进程定期与redis主从进行通信,当哨兵认为redis主服务“阵亡”时,自动进行切换工作
安装与使用
https://www.cnblogs.com/freeton/p/9112757.html
# 1. 安装redis-sentinel
sudo apt install redis-sentinel # ubuntu环境下
# 2. 新建配置文件sentinel.conf 可以启动奇数个哨兵(决策投票需要奇数)
port 26379
sentinel monitor <master-name> <ip> <redis-port> <quorm>
sentinel auth-pass <master-name> <password>
# master失联多久后不可用
sentinel down-after-milliseconds <master-name> <milliseconds>
# 3. 启动哨兵
方法一 redis-sentinel sentinel.conf
方法二 redis-sentinel sentinel.conf --sentinel
# 4. 终止master,检查从服务是否升级
python使用哨兵
# 使用前需要在服务器上先启动好哨兵
from redis.sentinel import sentinel
#生成哨兵连接
sentinel = sentine1([('localhost', 26379)],socket_timeout=0.1)
#初始化master连接
master = sentine1.master_for('master_name', socket_timeout=0.1,db=1)
slave = sentine1.slave_for('master_name', socket_timeout=0.1,db=1)
#使用redis相关命令
master.set( 'mymaster', 'yes')
print(slave.get('mymaster'))