Redis简介
**Nosql**
非关系型数据库,作为关系型数据库的补充
应对基于海量用户和海量数据前提下的数据处理问题
特征
可扩容,可伸缩
大数据量下高性能
灵活的数据模型
高可用
常用Nosql数据库
Redis
memcace
HBase
MongoDB
**Redis介绍**
概念是c语言开发的一个开源的高性能键值对数据库
特征
数据间没有必然的关联关系
内部采用单线程机制进行工作
高性能,50个并发执行100000个请求,读的速度是110000次/s,写的速度是81000次/s
多数据类型支持
字符串类型 string
列表类型 list
散列类型 hash
集合类型 set
有序集合类型 sorted---set
持久化支持。可以进行数据灾难恢复
**redis应用场景**
为热点数据加速查询
任务队列,如秒杀,抢购,购票排队
即时信息查询
时效性信息控制
分布式数据共享,如分布式集群架构中的session分离
消息队列
缓存
网站访问统计
数据过期处理
应用排行榜
**redis核心文件**
redis-server.exe:服务启动命令
redis-cli.exe:命令行客户端
redis.windows.conf:redis核心配置文件
redis-benchmark.exe:性能测试工具
redis-check-aof.exe:AOP文件修复工具
redis-check-dump.exe:RDB文件检查工具
将reids-server和redis-cli命令加入环境变量
redis数据类型
**string**
介绍
string类型是二进制安全的,可包含任何数据,是redis最基本 的数据类型
一个redis中字符串value最多可以是512M
String数据结构是简单的key-value类型,value其实不仅是String,也可以是数字
常用命令
set key value 赋值
get key 取值
del key #删除
append key # 追加
exists key # 判断某个key是否存在,1表示存在,0表示不存在
strlen key # 返回长度
move key db # 移动索引库,例如:move key1 5 将当前库中的key1移5号库
expire key 秒钟 # 为指定的key设置过期时间
ttl key # 查看还有多少秒过期,-1表示永不过期,-2表示已过期
type key # 查看你的key是什么类型
incr key # 将key中储存的数字值增一
decr key # 将key中储存的数字值减一
incrby key # 将key所储存的值加上给定的增量值(increment)
decrby key # 将key所储存的值减去给定的减量值(decrement)
getrange key startindex endindex # 获取指定区间值(0到-1获取全部)
SETRANGE key offset value # 修改指定区间值
setex key time(秒) # value 将值value关联到key,并将key的过期时间设为seconds(以秒为单位)
setnx key value # 只有在key不存在时设置 key 的值,如果已经存在则不设置值
mset key value [key2 value2 ...] # 同时设置一个或多个键值对
mget key [key2 key3 ...] # 获取所有(一个或多个)给定key的值
msetnx key value [key2 value2 ...] # 同时设置一个或多个键值对(key不存在时)在设置的过程中只要有一个失败,其他的都不会set成功
getset key value # 获取旧值,设置新值
**List**
介绍
数据存储需求:存储多个数据,并对数据进入存储空间的顺畅进行区分
需要的存储结构:一个存储空间保存多个数据,按照插入顺序排序
底层使用双向链表存储结构实现
常用命令
添加/修改数据
lpush key value1 [value2]...
rpush key value1 [value2]...
获取数据
lrange key start stop
lindex key index
llen key
获取并移除数据
lpop key
rpop key
规定时间内获取并移除数据
blpop key1 [key2] timeout
brpop key1 [key2] timeout
brpoplpush source destination timeout
移除指定数据
lrem key count value
ltrim key start end # 截取指定范围的值后再赋值给key(让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除)
lset key index value # 通过索引设置列表元素的值
linsert key BEFORE|AFTER pivot value # 在列表指定的元素前或者后插入元素
**set**
介绍
能够保存大量的数据,高效的内部存储机制,便于查询
是string类型的无序集合,它是通过HashTable实现的,不允许值重复
常用命令
sadd key value [value2 ...] # 向集合添加一个或多个成员
smembers key # 返回集合中的所有成员
sismember key member # 判断 member 元素是否是集合 key 的成员
scard key # 获取集合里面的元素个数
srem key value # 删除集合中指定元素
spop key [count] # 移除集合中一个随机元素并返这个元素(可选择删除数量)
srandmember key [coutn] # 随机返回集合中一个或多个值
smove key1 key2 # 将key1里的某个值赋给key2
sdiff key1 [key2] # 返回给定所有集合的差集
sinter key1 [key2] # 返回给定所有集合的交集
sunion key1 [key2] 返回所有给定集合的并集
**hash**
介绍
是一个键值对集合。是一个string类型的field和value的映射表
特别适合用于存储对象。类似域Java里面的Map集合
常用命令
hset key field value # 以hash方式存储
hget key field # 以hash方式获取
hmset key field value # [field value ...] 以hash方式存储一个或者多个
hmget key field # [field ...] 以hash方式获取一个或者多个
hgetall key # 获取在哈希表中指定key的所有字段和值
hdel key field [field ...] # 删除一个或多个哈希表字段
hkeys key # 获取所有哈希表中的字段
hvals key # 获取哈希表中所有值
hlen key # 获取哈希表中字段的数量
hexists key # 查看哈希表key中,指定的字段是否存在
hincrby key field value # 为哈希表key中的指定字段的整数值加上增量value(必须为数字)
hincrbyfloat key field value # 为哈希表key中的指定字段的浮点数值加上增量value
**sorted_set**
介绍
有序集合,不允许重复,可自动排序
常用命令
zadd key score1 member1 [score2 member2] 向有序集合添加一个或多个成员,或者更新已存在成员的分数
zrange key startindex endindex [WITHSCORES] 通过索引区间返回有序集合成指定区间内的成员(WITHSCORES带出分数)
zscore key member 返回有序集中,成员的分数值
zrangebyscore key min max [WITHSCORES] [LIMIT] 通过分数返回有序集合指定区间内的成员
zrem key member [member ...] 删除一个或多个元素
zcard key 获取有序集合的成员数
zcount key min max 计算在有序集合中指定区间分数的成员数
zrank key member 返回有序集合中指定成员的索引
zrevrank key member 返回有序集合中指定成员的排名,有序集成员按分数值递减(从大到小)排序
zrevrange key startindex endindex [WITHSCORES] 返回有序集中指定区间内的成员,通过索引,分数从高到底
zrevrangebyscore key max min [WITHSCORES] 返回有序集中指定分数区间内的成员,分数从高到低排序
Redis常用配置
**常用**
include /path/to/other.conf 包含一个文件
deamonize yes 是否开启守护进程
protected-mode yes 是否开启 保护模式,默认开启。yes:只允许本地进行访问,拒绝外部访问
pidfile /run/run/redis/redis-server.pid redis的进程文件
port 6379 redis监听的端口号
tcp-backlog 511 tcp连接队列的长度
bind 127.0.0.1指定redis只接收来自该IP地址的请求,如果不进行设置,那么将处理所有请求
timeout 0 当客户端闲置多长时间后关闭连接,如果指定为0,表示关闭该功能
loglevel notice指定日志级别
debug:便于开发,测试
verbose
notice:适当的日志级别,适合生产环境
warn(只有非常重要的信息)
databases 16 设置数据库的数量,默认数据库为0,可以使用select <dbid> 命令连接指定数据库id
**snapshotting(快照)**
save <seconds> <changes> <指定时间间隔> <执行指定次数更新操作>,满足条件就将内存中的数据同步到硬盘中
stop-writes-on-bgsave-error yes 当RDB持久化出现错误后是否继续进行工作,yes,不能,no,能
rdbccompression yes 使用压缩rdb文件,rdb文件压缩使用lzf压缩算法,yes,压缩,消耗cpu;no不压缩,需要更多的磁盘空间
rdbchecksum yes 是否校验rdb文件
dbfilename dump.rdb rdb文件名称
dir /var/lib/redis 数据目录,数据库的写入会在这个目录。rdb.aof文件也会写在这个目录
**replication(复制)**
slaveof <masterip> <masterport>
当本机为slave服务时,设置master服务的ip和端口,会自动从master进行数据同步
masterauth <master-password> 当master服务设置了密码保护时,slav服务连接master密码
slave-redis-only yes 作为从服务器,默认情况下是只读的,no是用于写
slave-priority 100 当master不可用,Sentinel会根据slave的优先级选举一个master。最低的优先级的slave,当选master.,而配置为0,永远不会被选举
**security(安全)**
requirepass foobared requirepass配置可以让用户使用auth命令来认证密码,才能使用其它命令
limit(限制)
maxclients 10000设置能连上redis的最大客户端连接数量,默认是10000个客户端连接
maxmemory<bytes> redis配置的最大内存容量。当内存满了,需要配合maxmemory-policy策略进行处理、
maxmemory-policy noeviction 内存容量超过maxmemory后的处理策略
volatile-lru利用LRU算法移除key,只对设置了过期时间的key
allkeys-lru:利用LRU算法移除所有key,与是否设置过期时间没关系
volaile-random:随机移除设置了过期时间的key
allkeys-randoms:随机移除任何key。与是否设置过期时间没关系
volatile-ttl:移除即将过期的key
noeviction:不移除任何key,只是返回一个写错误
**append only mode(追加)**
appendonly no 默认redis使用的是rdb方式持久化
appendfilename “appendonly.aof” aof文件名
appendfsync everysec aof 持久化策略的配置
no宝石不执行fsync,由系统包装数据同步到磁盘,速度最快
always 表示每次写入都执行fsync,以保证数据同步到磁盘
everysec表示每秒执行一次fsync,可能会导致丢失1s数据
auto-aof-rewrite-percentage 100 aof自动重写配置
auto-aof-rewrite-min-size 64mb 设置允许重写的最小aof文件大小,避免了达到约定百分比但尺寸仍然很小的情况还要重写
redis持久化(RDB/AOP)
**持久化简介**
什么是持久化
利用永久性存储介质将数据进行保存,在特定的事件将保存的数据进行保存,在特定的事件将保存的数据进行恢复的工作机制称为持久化
为什么要进行持久化
防止数据的意外丢失,确保数据安全性
持久化过程保存什么
将当前数据状态进行保存,快照形式,存储数据结构,存储格式简单,关注点在数据
将数据的操作过程进行保存,日志形式,存储操作过程,存储格式复杂,关注点在数据的操作过程
**RDB**
介绍
是redis默认的持久化,它可以在指定的事件间隔内将该内存中的数据集快照写入磁盘
启动方式
手动执行
save命令
执行时只管保存,其它不管,全部阻塞
bgsave命令
后台备份,在备份的同时可以处理输入的数据,bgsave则是调用fork,产生子进程,父进程继续处理请求
通过配置启动
save second changes
满足限定事件范围内key的变化数量达到指定数量就进行持久化
**AOF**
为什么要使用AOF*(RDB存储的弊端)
存储数据量较大,效率低,基于快照思想,每次读写都是全部数据,当数据量巨大时,效率非常低
大数据量下的IO性能较低
基于fork创建子进程,内存产生额外消耗
宕机带来的数据丢失风险
介绍
redis默认是不开启的,采用日志的形式来记录每个写操作,并追加到文件中
重启时在重新执行AOF文件中的命令达到恢复数据的目的
解决数据持久化的实时性
AOF写数据的三种策略(appendfsync)
always:每次写入操作都同步到AOF文件中
everysec:每秒将写入操作同步到AOF文件中
no:有操作系统控制每次操作同步到AOF文件的周期,整体过程不可控
AOF配置
appendonly yes|no
是否开启AOF持久化功能,默认不开启
appendfsync always|everysec|no
aof写数据策略
appendfilename filename
aof持久化文件名
dir
aof持久化文件保存路径,与rdb持久化保持一致即可
AOF重写
为什么要重写
命令不断写入AOF,文件越来越大
重写作用
降低磁盘占用量,提高磁盘利用率
提高持久化效率,降低持久化写时间,提高io性能
提高数据恢复效率
重写规则
进程内已超时的数据不再写入文件
忽略无效指令,只保留最终数据的写入命令
对同一数据的多条写命令合并为一条命令
重写方式
手动重写
bgrewriteaof
自动重写
auto-aof-rewrite-min-size size
auto-aof-rewrite-percentage percentage
**RDB和AOF比较**
优势
RDB:适合大规模的数据恢复
AOF:数据的完整性和一致性更高
劣势
RDB数据的完整性和一致性不高,可能在备份时宕机,创建的子进程还会占用内存
AOF记录的内容越多,文件越大,数据恢复越慢
redis事务
**什么是事务**
redis事务就是一个命令执行的队列,将一系列预定义命令包装成一个整体
一个队列中,一次性,顺序性,排他性的执行一系列命令
**基本操作**
multi开启事务
exec执行事务
discard取消事务
**事务监控**
可以监控一个或多个键,一旦其中有一个键被修改,之后的事务就不会执行
watch key [key..]监控键
unwatch 取消对所有key的监控
消息发布订阅
**消息发布订阅是什么**
是一种消息通信模式:发送者发送消息,订阅者接收消息
**发布订阅命令**
psubscribe 订阅一个或多个频道
pubsub subcommand 查看订阅与发布系统状态
publish channel message 将信息发送到指定的频道
punsubscribe 退订所有给定模式的频道
subscribe channel 订阅给定的一个或多个频道的信息
unsubcribe 指退订给定的频道
高级数据类型
**bitemaps**
获取指定key对应偏移量上的bit值:getbit key offset
设置指定key对应偏移量上的bit值,value只能时1或0:setbit key offset value
统计指定key中1的数量:bitcount key [start end]
**hyperloglog**
添加数据:pfadd key element [element....]
统计数据:pfcount key [key.....]
合并数据:pfmerge destkey sourcekey [sourcekey....]
**geo**
添加坐标点:geoadd key longitude latitude member
获取坐标点:geopos key member [member....]
计算坐标点距离:geodist key member1 member2 [unit]
添加坐标点:georadius key longitude latitude latitude
获取坐标点:georadiusbymember key member radius
计算经纬度:geohash key member [member ....]
主从复制
**为什么要使用主从复制**
解决redis服务器宕机引起的数据丢失问题
**配置主从**
slaveof host prot认主
info [section] 查看redis信息
slaveof no one 将从库转成主库,并保存已有数据
**主从复制的作用**
读写分离
mater写,slave读,提高服务器的读写负载能力
负载均衡
基于主从结构,配合读写分离,有slave分担master负载
故障恢复
当master出现问题时,有slave提供服务,实现快速的故障恢复
高可用基石
基于主从复制,构建哨兵模式与集群,实现Redis的高可用方案
**主从复制的工作流程**
建立连接阶段
建立slave到master的连接,使master能够识别slave,并保存slave端口号
数据同步阶段
在slave初次连接master后,复制master中的所有数据到slave
在slave的数据库状态更新成master当前的数据库状态
命令传播阶段
当master数据库状态被修改后,导致主从服务器数据库状态不一致,此时需要让主从数据同步到一致状态,同步的动作称为命令传播
哨兵模式
**什么是哨兵**
哨兵是一个分布式系统,用于对主从结构中的每台服务器进行监控,当出现故障时通过投票机制选择新的master并将所有slave连接到新的master
**哨兵的作用**
监控master和slave是否正常运行
当被监控服务器出现问题时,向其它哨兵发送通知
当master故障后,会选举一个slave作为master,将其它的slave连接到新的master
**启动哨兵模式的配置**
在sentinel.conf配置文件中配置 sentinel monitor mymaster 192.168.19.129 6379 1
启动哨兵:redis-sentinel sentinel.conf
**哨兵工作原理**
监控阶段
监控各个节点的状态信息
通知阶段
当服务器出现问题时,就向其它哨兵发送通知
故障转移阶段
当master故障后,会选去一个slave为master,让其他的slave去连接这个新的master
企业级解决方案
**缓存预热**
概念
就系统上线后,提前将相关的缓存数据加载到缓存系统,避免在用户请求时,先查询数据库,在将数据缓存的问题
解决方案
把该放的数据提前放到redis缓存中
把访问量高的热点数据写入到redis中
**缓存雪崩**
概念
原有的缓存失效,数据库的访问量剧增,容易导致数据库宕机,从而影响到redis缓存
解决方案
加锁排队,但在高并发场景下,会导致线程阻塞,用户等待超时
把缓存的失效时间分散
设置过期标记更新缓存
**缓存击穿**
概念
缓存中的某个key过期了,刚好在这个时候有大量对这个key的并发请求,这些请求转而去访问数据库去获取数据,容易导致数据库宕机而引发一系列问题
解决方案
使用互斥锁,对缓存查询加锁,如果key不存在就加锁,存在就解锁
**缓存穿透**
概念
用户查询的数据在数据库和缓存里都没有,导致两次无用查询
解决方案
使用布隆过滤器,将可能存在的数据存在一个bitmap中,不可能存在的数据会被bitmap拦截
把空结果也缓存起来
**缓存降级**
概念
访问量剧增,影响到了服务的性能,所以会对一下关键数据进行自动降级
解决方案
一般:自动降级
警告:自动降级或人工降级
错误:自动降级或人工降级
严重错误:需要紧急人工降级
**缓存更新**
概念
缓存过期了,或者一些缓存不满足业务的需求,需要淘汰
解决方案
定时清理过期的缓存
判断请求用到的缓存是否过期,过期就去数据库得到新数据并更新缓存