数据库之Redis
- ����,����
- 特点
速度快,存放与内存
支持丰富的数据类型:字符串、数组、集合、有序集合、hash
支持事务,操作都是原子性
支持持久化
- 16个库,默认0库【select 1】默认端口6379
- 与memcache比较
memcache只支持字符串,redis支持5中
redis要快
redis支持持久化,memcache不支持
- redis支持value的max大小为1GB,memcache只1MB
- 优化
高可用,主从复制,使用单向链表结构,即:master < slave1 < slave2……这样的结构方便解决单点故障问题,实现slave对master的替换,如果master挂了,可以立即启用slave1做master,其它不变。
master不做持久化工作,如果数据比较重要,某个slave开启aof备份,每秒同步一次
master和slave在同一个局域网内,保持稳定性
- 避免在压力大的主库上增加从库
redis过期策略【总共6种】
- 总结起来就是从设置过期的数据集中,挑选使用少的,将要过期的,任意选,或者从总的数据中挑选使用少的,或任意,或不允许淘汰
voltile-lru: 从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰
volatile-tt1:从已设置过期时间的数据集,中挑选将要过期的数据淘汰
volatile-random:从已设置过期时间的数据集,任意选择数据淘汰
allkeys-lru: 从数据集中挑选最近最少使用的数据淘汰
allkeys-random:从数据集中任意选择数据淘汰
- no-enviction(驱逐):禁止驱逐数据
- 使用场景
会话缓存,如购物车,权限信息
全页缓存
消息队列
排行榜、计数器
- 发布订阅,IM通讯
- 安装
# 配置阿里yum源或epel源yum list redisyum install redis -ysystemctl start redis# 查看连接redis-cli127.0.0.1:6379> ping# 编译安装,默认安装目录在/usr/local/binwget http://download.redis.io/releases/redis-4.0.10.tar.gztar -zxf redis-4.0.10.tar.gzcd redis-4.0.10.tar.gzmake && make installecho 'export PATH="$PATH:/usr/local/bin"' >> /etc/profilesource /etc/profile# 启动redis-server # redis 可以开多实例,可以指定配置文件redis-server /redis_etc/redis_6379.conf# 查看redis信息redis-cli info # 查看redis数据库信息redis-cli info replication # 查看redis复制授权信息redis-cli info sentinel # 查看哨兵信息
- redis配置文件redis.conf
绑定ip,如需要远程访问,需要填写服务器ip
bind 127.0.0.1
端口,redis启动端口
port
守护进程方式运行
daemonize yes
rdb数据文件
dbfilename dump.rdb
数据文件存放路径
dir /var/lib/redis/
日志文件
logfile /var/log/redis/redis-server.log
主从复制
slaveof
配置密码
requirepass redhat
保护模式,是否允许远程用户登录,哨兵时需要关闭
protected-mode no
* redis持久化redis 支持两种持久化RDB和AOFRDB是在指定的时间间隔内生成数据集的时间点快照优点:快,一般就是通过rdb做的缺点:可能导致数据丢失主要有:save 900 1 1个修改类的操作, 即每过900秒,有1个操作就进行持久化save 300 10 10个操作save 60 10000 10000个操作AOF是记录所有的操作命令,在服务器启动时重新执行优点:安全最大程度保证数据不丢失缺点:日志记录很大1. RDB持久化配置
daemonize yes
port 6379
bind 10.0.0.10 127.0.0.1 #redis绑定地址
loglevel warming
logfile /data/6379/redis.log
dir /data/6379 #定义持久化文件存储位置
dbfilename dbmp.rdb #rdb持久化文件
requirepass redhat #redis登录密码
save 900 1 #rdb机制 每900秒 有1个修改记录
2.AOF持久化
daemonize yes
port 6379
bind 10.0.0.10 127.0.0.1 #redis绑定地址
loglevel warming
logfile /data/6379/redis.log
dir /data/6379
dbfilename dbmp.rdb
requirepass redhat
save 900 1
save 300 10
save 60 10000
appendonly yes # 开启aof
appendfsync everysec # 每秒进行一次
* redis主从复制1.master
port 6379
bind 10.0.0.10
daemonize yes
logfile "6379.log"
dbfilename "dump-6379.rdb"
dir "/var/redis/data/"
masterauth redis # 主库的密码
2.slave
port 6380
bind 10.0.0.11
daemonize yes
logfile "6380.log"
dbfilename "dump-6380.rdb"
dir "/var/redis/data/"
slaveof 10.0.0.10 6379 # 从属主节点
masterauth redis # 主库的密码
* redis主从复制高可用哨兵模式sentinel 哨兵模式,通过它时刻监视master,每秒ping一下master,如果超过规定时间及次数,就标记master挂了,如果多个哨兵都认为其挂了,就选一个slave当master1. 准备一主二从1. 自定义编辑sentinel_26379.conf文件
port 26379
dir /var/redis/data/
logfile "26379.log"
#当前Sentinel节点监控 10.0.0.10:6379 这个主节点
#2代表判断主节点失败至少需要2个Sentinel节点节点同意
sentinel monitor mymaster 10.0.0.10 6379 2
sentinel auth-pass mymaster redis
sentinel down-after-milliseconds mymaster 30000
当Sentinel节点集合对主节点故障判定达成一致时,Sentinel领导者节点会做故障转移操作,选出新的主节点,#原来的从节点会向新的主节点发起复制操作,限制每次向新的主节点发起复制操作的从节点个数为1
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
protected-mode no # 关闭保护模式,防止哨兵不能通信
3.配置另2个sentinel文件,仅仅是端口不同而已4.然后启动哨兵
redis-sentinel /etc/redis-sentinel-26379.conf
redis-sentinel /etc/redis-sentinel-26380.conf
redis-sentinel /etc/redis-sentinel-26381.conf
* redis集群* python操作redis1. 连接redis
import redis
r_cli = redis.Redis(host='127.0.0.1', port=6379, password=123456)
r_cli.set('name', 'string_value')
ret = r_cli.get('name') # 返回的都是bytes
2.连接池
pool = redis.ConnectionPool(host='localhost', port=6379, password=123456)
r_cli = redis.Redis(connection_pool=pool,max_connections=100)
3.5种数据类型操作
str字符串r_cli.set('name', 'sun')
r_cli.get('name')
r_cli.mset({'name1': 11, 'name': 22})
r_cli.mget('name1', 'name')
ret = r_cli.mget(['name1', 'name'])
r_cli.hset('hash_name', 'project', 'age')
r_cli.hget('hash_name', 'project')
r_cli.hmset('namexxx', {'1': 1, '2': 2, '3': 3})
r_cli.hmget('namexxx', '1', '2')
r_cli.hmget('namexxx', ['1', '2'])
r_cli.hgetall('namexxx')
r_cli.lpush('li_name', 1, 2, 3)
r_cli.lrange('li_name', 0, -1) # 按索引范围获取
r_cli.llen('li_name')
r_cli.lpop('li_name') # 删左边第一个,返回删除值
r_cli.sadd('set_name', 1, 2, 3)
r_cli.smembers('set_name') # 获取集合所有值
r_cli.spop('set_name') # 从后面删
r_cli.zadd('zadd_name', {'wuhan': 1000, 'bj': 100}) # 前面是key,后面是分值
r_cli.zcard('zadd_name') # 获取name的集合元素数量
r_cli.zcount('zadd_name', 0, 100) # 获取分值在0~100间的个数
r_cli.zrange('zadd_name', 0, -1) # 按索引获取对应name的key