Redis学习系列第二篇笔记,将学习Redis持久化、Redis事务、Redis删除策略、Redis配置文件以及高级数据类型。
$tar -xvf redis-VERSION.tar.gz
$cd redis-VERSION
$make install
#服务端从6380端口启动
$redis-server --port 6380
#客户端从6380端口连接
$redis-cli -p 6380
配置文件如下:
bind 127.0.0.1
port 6379
daemonize yes
按照守护进程方式启动logfile "6379.log"
日志文件的存储路径dir ./
上面的文件存储在哪儿从配置文件启动:
$redis-server redis.conf
如果想启动多个Redis服务,只需稍微修改下配置文件即可。
利用永久性介质将数据进行保存,在特定的时间将保存的数据进行恢复的工作机制叫做持久化。
为了防止数据丢失。
数据持久化的两种形式:
手动执行save
指令,会立即生成dump.rdb文件。
rdb相关配置
dbfilename dump.rdb
一般设置为dump-端口号.rdb,方便查看。dir
存储rdb文件的路径。rdbcompression yes
默认会压缩数据。rdbchecksum yes
默认会开启,数据校验,防止数据出错。save指令工作原理
save指令会阻塞服务器,有可能造成长时间阻塞。不建议线上环境使用。
后台会在某个时间执行保存操作。
执行过程:
客户端发送bgsave
指令,服务端返回给客户端Background saving started
消息,同时调用fork函数生成一个子进程来创建rdb文件。
注意:
bgsave命令对save的阻塞进行了优化,Redis内部所有涉及到RDB的操作都采用了bgsave的方式。
stop-writes-on-bgsave-error yes
后台存储时如果出现了错误,是否停止保存。默认是yes。在conf文件内进行配置。
save seconds changes
方式 | save | bgsave |
---|---|---|
读写 | 同步 | 异步 |
是否阻塞服务端 | 是 | 否 |
额外内存 | 否 | 是 |
启动新进程 | 否 | 是 |
debug reload
shutdown save
优点:
缺点:
AOF
, append only file, 目前是Redis实时持久化的主流方式。
AOF写数据的三种策略:
always
每次,数据零误差,性能较低。不建议使用。everysec
每秒,每秒将缓冲区的命令同步到AOF文件内,可能会丢失一秒的数据。Redis默认。no
系统控制,过程不可控。在conf文件中启用AOF:
# 开启AOF, 默认是no
appendonly yes|no
# 配置AOF写数据策略
appendfsync always|everysec|no
# 配置AOF文件名
appendfilename filename
重写规则:
重写命令
手动重写:
bgrewriteaof
自动重写:
Redis事务就是一个命令执行的队列,将一系列预定义的命令包装成一个整体。当执行时,一次性按照顺序执行,中间不会被打断。
事务的边界:
开头:multi
, 结尾:exec
。
取消事务:discard
如果有错误的指令,那么所有的操作都会被清除。
正确的命令会执行,错误的指令不会执行。
已经执行完毕的命令对应的数据不会自动回滚。
基于特定条件的事务执行----锁。
对key添加监视锁,在exec之前如果key发生了变化,则不执行。
watch key1 [key2...]
unwatch
取消对所有key的监视。注意:事务中不能watch。
如何避免最后一件商品被多个人买到?
分布式锁,类似于Java的同步代码块。
使用setnx设置一个公共锁
setnx lock-key value
有值则返回失败,没有值则返回设置成功。
可以理解为厕所钥匙。
操作完毕后通过del
删除锁。
如果客户端拿到分布式锁后客户端宕机了怎么办?
给锁设置时效性。
expire lock-key second
pexpire lock-key 毫秒
已经过期的数据真的被删除了吗?
Redis数据有三种状态:
set和get的优先级比较高,del优先级低。过期的数据不一定被立刻删除,可能还会留一段时间。
Redis内部会有一个expires空间,里面是[数据的内存地址-过期时间]
的形式。
删除策略:在CPU和内存之间找一个平衡。
key的过期时间到了后定时器立刻去删除数据。
数据到期后不做处理,如果过期后有人访问这个数据,发现过期了,删除,返回不存在。
启动时,将server.hz设置为10,每秒钟执行hz次serverCron()->databaseCron()->activeExpireCycle()。
activeExpireCycle()对每个expire空间逐一进行检测,每次执行(250/hz) ms
随机挑w个key进行检测,如果key超时,就删除。如果删除的量超过了w的25%,那么就会接着执行这个过程。
参数current_db用以记录activeExpireCycle()执行到了哪个db。
w取值由配置文件决定。ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP
如果数据进入Redis时内存不够了怎么办?
临时删除一些数据,称为数据逐出/淘汰,这个策略称为逐出算法。
逐出算法可能会失败,如果失败了,会报错。
影响逐出算法的配置:
maxmemory
maxmemory-samples
每次选取待删除数据的个数。
maxmemory-policy
检查易失数据。(在expires里面删除数据)
检测全库数据(在dict中删除数据)
放弃数据逐出(Redis4.0开始的默认操作)
配置文件:maxmemory-policy 逐出策略
注意:
查看INFO信息中的命中缓存次数及未命中次数,根据这个信息来调优。
服务器基础配置
设置服务器以守护进程的方式运行
daemonize yes|no
绑定主机地址(使之只能让这个地址来访问)
bind 127.0.0.1
设置端口
port 6379
设置数据库数量
databases 16
日志配置
指定日志级别
loglevel debug|verbose|notice|warning
日志记录文件名
logfile 端口号.log
服务端对客户端的配置
设定同一时间内最大客户端连接数,0代表无限制。
maxclients 0
客户端闲置最大时长,0代表不关闭。
timeout 300
多服务器快捷配置
导入并加载指定位置的配置文件,用于快捷创建Redis公共配置较多的Redis实例配置文件。
include /path/某个端口号.conf
高级数据类型更倾向于解决一种问题,应用面比较狭窄。
获取指定key上对应偏移量上的bit值
getbit key offset
设定指定key上对应偏移量的值
setbit key offset value
统计指定key中1的个数
bitcount key [start end]
对指定的key进行位运算
bitop op destKey key1 [key2 key3...]
destKey 是目标key,结果存进这个key里。
op有四种,交并非异或。
and 交(&&)
or 并 (||)
not 非 (!)
xor 异或 (^)
比如统计UV独立用户,HyperLogLog应用面更窄,用来做基数统计。
内部用了LogLog算法。
添加数据
pfadd key value1 [value2 value3...]
统计数据
pfcount key1 [key2 key3...]
合并数据
pfmerge destKey key1 [key2 key3...]
注意:
求两个点的距离(关联关系)。
添加坐标点
geoadd key 横坐标1 纵坐标1 value1 [横坐标2 纵坐标2 value2 ...]
取出来坐标
geopos key value
计算距离
geodist key value1 value2 [m/km/ft/mi]
根据坐标求范围内的数据
georadius key 经度 维度 半径 m/km/ft/mi [WITHCOORD WITHDIST WITHHASH] [COUNT count]
根据点求范围内数据
geiradiusbymember key value 半径 单位 [后面的同上]
求坐标哈希值
geohash key value1 [value2...]