redis基础学习文档
一、介绍
Redis:Remote DIctionary Server(远程字典服务器),是完全开源免费的,用C语言编写的,遵守BSD协议,
是一个高性能的(key/value)分布式内存数据库,基于内存运行并支持持久化的NoSQL数据库,是当前最热门的NoSql数据库之一,也被人们称为数据结构服务器。
优点:
(1)Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用
(2)Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储
(3)Redis支持数据的备份,即master-slave模式的数据备份
相关应用:
(1)内存存储和持久化:redis支持异步将内存中的数据写到硬盘上,同时不影响继续服务
(2)取最新N个数据的操作,如:可以将最新的10条评论的ID放在Redis的List集合里面
(3)模拟类似于HttpSession这种需要设定过期时间的功能
(4)发布、订阅消息系统
(5)定时器、计数器
二、Redis的安装
下载安装
1 |
|
安装目录查看
查看默认安装目录:usr/local/bin
redis-benchmark:性能测试工具
redis-check-aof:修复有问题的AOF文件
redis-check-dump:修复有问题的dump.rdb文件
redis-cli:客户端,操作入口
redis-sentinel:redis集群使用
redis-server:Redis服务器启动命令
启动服务
(1)修改redis.conf文件将里面的daemonize no 改成 yes,让服务在后台启动
(2)将默认的redis.conf拷贝到自己定义好的一个路径下,比如/myconf
(3)通过命令redis-server /myconf启动服务
(4)redis-cli 连接测试
服务关闭
单实例关闭:redis-cli shutdown
多实例关闭,指定端口关闭:redis-cli -p 6379 shutdown
三、Redis服务
服务核心
单进程
单进程模型来处理客户端的请求。对读写等事件的响应是通过对epoll函数的包装来做到的。Redis的实际处理速度完全依靠主进程的执行效率。
epoll是Linux内核为处理大批量文件描述符而作了改进的epoll,是Linux下多路复用IO接口select/poll的增强版本,它能显著提高程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率。
服务端操作
默认16个数据库,类似数组下表从零开始,初始默认使用零号库。
设置数据库的数量,默认数据库为0,可以使用SELECT
默认端口是6379
数据库操作
select命令切换数据库:select [index]
dbsize查看当前数据库的key的数量
flushdb:清空当前库
flushall:清空全部库
统一密码管理,16个库都是同样密码,要么都OK要么一个也连接不上
Redis索引都是从零开始
更多操作
四、Redis数据类型
https://blog.csdn.net/weixin_40205234/article/details/124614720
Redis的五大数据类型:
(1)string(字符串)
(2)hash(哈希,类似java里的Map)
(3)list(列表)
(4)set(集合)
(5)zset(sorted set:有序集合)
1 |
|
Redis 键(key)
key值查看:
1 |
|
更多操作:http://redisdoc.com/database/index.html
Redis字符串(String)
string是redis最基本的类型,一个key对应一个value。
string类型是二进制安全的。意思是redis的string可以包含任何数据。比如jpg图片或者序列化的对象 。
string类型是Redis最基本的数据类型,一个redis中字符串value最多可以是512M。
应用场景:共享session、分布式锁,计数器、限流。
内部编码有3种,int(8字节长整型)/embstr(小于等于39字节字符串)/raw(大于39个字节字符串)
1 |
|
相关操作:
1 |
|
所有字符串类型操作:http://redisdoc.com/string/index.html
Redis列表(List)
Redis 列表是简单的字符串列表,按照插入顺序排序。可以添加一个元素导列表的头部(左边)或者尾部(右边)。它的底层实际是个链表。
简介:列表(list)类型是用来存储多个有序的字符串,一个列表最多可以存储2^32-1个元素。
简单实用举例:lpush key value [value …] 、lrange key start end
内部编码:ziplist(压缩列表)、linkedlist(链表)
应用场景:消息队列,文章列表
list应用场景参考以下:
1 |
|
相关操作:
1 |
|
所有列表操作:http://redisdoc.com/list/index.html
Redis集合(Set)
简介:集合(set)类型也是用来保存多个的字符串元素,但是不允许重复元素
简单使用举例:sadd key element [element …]、smembers key
内部编码:intset(整数集合)、hashtable(哈希表)
注意点:smembers和lrange、hgetall都属于比较重的命令,如果元素过多存在阻塞Redis的可能性,可以使用sscan来完成。
应用场景:用户标签,生成随机数抽奖、社交需求。
相关操作:
1 |
|
所有Set集合操作:http://redisdoc.com/set/index.html
Redis哈希(Hash)
简介:在Redis中,哈希类型是指v(值)本身又是一个键值对(k-v)结构
简单使用举例:hset key field value 、hget key field
内部编码:ziplist(压缩列表) 、hashtable(哈希表)
应用场景:缓存用户信息等。
注意点:如果开发使用hgetall,哈希元素比较多的话,可能导致Redis阻塞,可以使用hscan。而如果只是获取部分field,建议使用hmget。
相关操作:
1 |
|
所有Hash操作:http://redisdoc.com/hash/index.html
Redis有序集合Zset(sorted set)
- 简介:已排序的字符串集合,同时元素不能重复
- 简单格式举例:
zadd key score member [score member ...]
,zrank key member
- 底层内部编码:
ziplist(压缩列表)
、skiplist(跳跃表)
- 应用场景:排行榜,社交需求(如用户点赞)
相关操作:
1 |
|
所有操作:http://redisdoc.com/sorted_set/index.html
Redis 的三种特殊数据类型
Geo:Redis3.2推出的,地理位置定位,用于存储地理位置信息,并对存储的信息进行操作。
HyperLogLog:用来做基数统计算法的数据结构,如统计网站的UV。
Bitmaps :用一个比特位来映射某个元素的状态,在Redis中,它的底层是基于字符串类型实现的,可以把bitmaps成作一个以比特位为单位的数组
五、redis配置文件
https://www.cnblogs.com/zhang-ke/p/5981108.html
1 |
|
六、redis持久化
RDB
原理
在指定的时间间隔内将内存中的数据集快照写入磁盘,也就是行话讲的Snapshot快照,它恢复时是将快照文件直接读到内存里。
Redis会单独创建(fork)一个子进程来进行持久化,会先将数据写入到一个临时文件中,待持久化过程都结束了,再用这个临时文件替换上次持久化好的文件。整个过程中,主进程是不进行任何IO操作的,这就确保了极高的性能如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。RDB的缺点是最后一次持久化后的数据可能丢失。
fork的作用是复制一个与当前进程一样的进程。新进程的所有数据(变量、环境变量、程序计数器等)数值都和原进程一致,但是是一个全新的进程,并作为原进程的子进程。
保存方案
rdb 保存的是dump.rdb文件。
save命令只管保存,其它不管,全部阻塞。
Redis会在后台异步进行快照操作,快照同时还可以响应客户端请求。可以通过lastsave命令获取最后一次成功执行快照的时间。
RDB持久化恢复方案
将备份文件 (dump.rdb) 移动到 redis 安装目录并启动服务即可,CONFIG GET dir获取目录,指定配置文件的dir 路径,dir默认当前目录。
优势与劣势
优势:
(1)适合大规模的数据恢复
(2)对数据完整性和一致性要求不高
劣势:
(1)在一定间隔时间做一次备份,所以如果redis意外down掉的话,就会丢失最后一次快照后的所有修改。
(2)fork的时候,内存中的数据被克隆了一份,大致2倍的膨胀性需要考虑
动态停止保存方法:
动态所有停止RDB保存规则的方法:redis-cli config set save “”
AOF(Append Only File)
原理
以日志的形式来记录每个写操作,将Redis执行过的所有写指令记录下来(读操作不记录),只许追加文件但不可以改写文件,redis启动之初会读取该文件重新构建数据,换言之,redis重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作。
配置文件
Aof保存的是appendonly.aof文件,可以在redis.conf修改文件名。
修改默认的appendonly no,改为yes
1 |
|
AOF启动/修复/恢复
将有数据的aof文件复制一份保存到对应目录(config get dir),然后重启redis进行加载而恢复数据。
如果AOP文件存在数据异常,可以使用redis-check-aof –fix进行修复。
rewrite
AOF采用文件追加方式,文件会越来越大为避免出现此种情况,新增了重写机制,当AOF文件的大小超过所设定的阈值时,Redis就会启动AOF文件的内容压缩,只保留可以恢复数据的最小指令集.可以使用命令bgrewriteaof
重写原理:
AOF文件持续增长而过大时,会fork出一条新进程来将文件重写(也是先写临时文件最后再rename),遍历新进程的内存中数据,每条记录有一条的Set语句。重写aof文件的操作,并没有读取旧的aof文件,而是将整个内存中的数据库内容用命令的方式重写了一个新的aof文件,这点和快照有点类似。
触发机制:
Redis会记录上次重写时的AOF大小,默认配置是当AOF文件大小是上次rewrite后大小的一倍且文件大于64M时触发。
AOF优势与劣势
优势:
(1)每修改同步:appendfsync always 同步持久化 每次发生数据变更会被立即记录到磁盘 性能较差但数据完整性比较好.
(2)每秒同步:appendfsync everysec 异步操作,每秒记录 如果一秒内宕机,有数据丢失,但数据丢失小。
(3)不同步:appendfsync no 从不同步,性能好。
劣势:
(1)相同数据集的数据而言aof文件要远大于rdb文件,恢复速度慢于rdb
(2)aof运行效率要慢于rdb,每秒同步策略效率较好,不同步效率和rdb相同
持久化方案总结
如果只希望数据在服务器运行的时候存在,可以不使用任何持久化方式.
方案对比:
RDB持久化方式能够在指定的时间间隔能对你的数据进行快照存储。
AOF持久化方式记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据,AOF命令以redis协议追加保存每次写的操作到文件末尾.Redis还能对AOF文件进行后台重写,使得AOF文件的体积不至于过大
同时开启两种持久化方式:
在这种情况下,当redis重启的时候会优先载入AOF文件来恢复原始的数据,因为在通常情况下AOF文件保存的数据集要比RDB文件保存的数据集要完整.
RDB的数据不实时,同时使用两者时服务器重启也只会找AOF文件。那要不要只使用AOF呢?
作者建议不要,因为RDB更适合用于备份数据库(AOF在不断变化不好备份),快速重启,而且不会有AOF可能潜在的bug,留着作为一个万一的手段。
七、Redis事务
可以一次执行多个命令,本质是一组命令的集合。一个事务中的所有命令都会序列化,按顺序地串行化执行而不会被其它命令插入,不许加塞。一个队列中,一次性、顺序性、排他性的执行一系列命令。
操作流程
(1)开启:以MULTI开始一个事务
(2)入队:将多个命令入队到事务中,接到这些命令并不会立即执行,而是放到等待执行的事务队列里面
(3)执行:由EXEC命令触发事务
事务
基本命令
http://redisdoc.com/transaction/index.html
1 |
|
执行情况
基本操作
(1)全部正常执行,即事务中的命令全部执行成功
(2)放弃事务,即放弃在事务中的所有操作
(3)全部执行失败(事务中队列中的执行操作,有语法错误)。
(4)部分执行(若队列中命令无语法错误,则全部执行,执行过程报错的不影响其它命令,例如:一个字符串k1=”vvsdf”,执行操作 incr k1不会报语法错误,但会报执行错误)
watch监控
悲观锁(Pessimistic Lock), 顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。
乐观锁(Optimistic Lock), 顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。乐观锁适用于多读的应用类型,这样可以提高吞吐量,
乐观锁策略:提交版本必须大于记录当前版本才能执行更新。
Watch原理:
Watch指令,类似乐观锁,事务提交时,如果Key的值已被别的客户端改变,比如某个list已被别的客户端push/pop过了,整个事务队列都不会被执行。
通过WATCH命令在事务执行之前监控了多个Keys,倘若在WATCH之后有任何Key的值发生了变化,EXEC命令执行的事务都将被放弃,同时返回Nullmulti-bulk应答以通知调用者事务执行失败。
Watch执行流程:
(1)WATCH 监视一个(或多个) key
(2)MULTI标记一个事务块的开始
(3)执行操作
(4)情况一:监控了key,如果key被修改了,后面一个事务的执行失效, WATCH 取消对所有 key 的监视
情况二:执行exec 把MULTI队列中的命令全部执行完成,并且WATCH监控锁也会被取消掉。
分布式锁
特性
单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。
没有隔离级别的概念:队列中的命令没有提交之前都不会实际的被执行,因为事务提交前任何指令都不会被实际执行,也就不存在”事务内的查询要看到事务里的更新,在事务外查询不能看到”这个让人万分头痛的问题。
不保证原子性:redis同一个事务中如果有一条命令执行失败,其后的命令仍然会被执行,没有回滚。
八、Redis的发布订阅
简介
进程间的一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息。
Redis 客户端可以订阅任意数量的频道。
订阅发布消息图
例:频道 channel1 , 以及订阅这个频道的三个客户端 —— client2 、 client5 和 client1 之间的关系图
当有新消息通过 PUBLISH 命令发送给频道 channel1 时, 这个消息就会被发送给订阅它的三个客户端:
操作命令
http://redisdoc.com/pubsub/index.html
PSUBSCRIBE pattern [pattern …] 订阅一个或多个符合给定模式的频道。
PUBSUB subcommand [argument [argument …]] 查看订阅与发布系统状态。
PUBLISH channel message 将信息发送到指定的频道。
PUNSUBSCRIBE [pattern [pattern …]] 退订所有给定模式的频道。
SUBSCRIBE channel [channel …] 订阅给定的一个或多个频道的信息。
UNSUBSCRIBE [channel [channel …]] 指退订给定的频道。
操作实例:
在redis客服端创建订阅频道channel1:
1 |
|
重新开启一个redis客服端,然后在同一个频道 redisChat 发布消息,订阅者就能接收到消息。
1 |
|
九、Redis的复制(Master/Slave)
简介
Redis支持简单的主从(master-slave)复制功能,当主Redis服务器更新数据时能将数据自动同步到从Redis服务器 ,Master以写为主,Slave以读为主。
主要用途
读写分离、容灾恢复
配置搭建
原则
配从(库)不配主(库),从库是不能进行修改操作的。
模式
http://redisdoc.com/replication/slaveof.html
每次与master断开之后,都需要重新连接,除非你配置进redis.conf文件
例如有3台redis服务器,分别是A、B、C。
一主二从
以A为主(master)库,B、C为从库。
在B、C上分别执行slaveof 127.0.0.1 6379,然后A库上所有的更新操作都能在B、C中存在。
A:
1 |
|
B:
1 |
|
C:
1 |
|
薪火相传
上一个Slave可以是下一个slave的Master,Slave同样可以接收其他slaves的连接和同步请求,那么该slave作为了链条中下一个的master,可以有效减轻master的写压力。
中途变更转向:会清除之前的数据,重新建立拷贝最新的。
A(master)为主库
B作为A库的slave,作为C库的master
C为B库的slave
A:
1 |
|
B:
1 |
|
C:
1 |
|
反客为主
使当前数据库停止与其他数据库的同步,转成主数据库。
SLAVEOF no one
哨兵模式(sentinel)
介绍
反客为主的自动版,能够后台监控主机是否故障,如果故障了根据投票数自动将从库转换为主库。
例如:当原有的master挂了,剩下的slave会投票选举出新的master,如果之前的master库重新启动了,则会成为同步新选举出来的master的slave从库。
一组sentinel能同时监控多个Master。
步骤
(1)在redis.conf对应目录下新建sentinel.conf文件。并且配置哨兵:
sentinel monitor 自定义被监控redis库 127.0.0.1 6379 1
上面最后一个数字1,表示主机挂掉后salve投票看让谁接替成为主机,得票数多少后成为主机。
例如:监控A库
sentinel.conf:
1 |
|
(2)启动哨兵
1 |
|
复制原理
slave启动成功连接到master后会发送一个sync命令
Master接到命令启动后台的存盘进程,同时收集所有接收到的用于修改数据集命令,在后台进程执行完毕之后,master将传送整个数据文件到slave,以完成一次完全同步
全量复制:而slave服务在接收到数据库文件数据后,将其存盘并加载到内存中。
增量复制:Master继续将新的所有收集到的修改命令依次传给slave,完成同步,但是只要是重新连接master,一次完全同步(全量复制)将被自动执行
例:当slave第一次连上master会全量复制,后面进行的是增量复制
复制缺点
复制延时:
由于所有的写操作都是先在Master上操作,然后同步更新到Slave上,所以从Master同步到Slave机器有一定的延迟,当系统很繁忙的时候,延迟问题会更加严重,Slave机器数量的增加也会使这个问题更加严重。
Jedis
基础
Jedis是 Redis 官方首选的 Java 客户端开发包。
开发需要的jar包:commons-pool-1.6.jar、jedis-2.1.0.jar
maven:
1 |
|
常用操作
连接测试
1 |
|
基本类型操作
1 |
|
事务控制
1 |
|
主从复制
1 |
|
Jedis池
获取Jedis实例需要从JedisPool中获取,用完Jedis实例需要返还给JedisPool,如果Jedis在使用过程中出错,则也需要还给JedisPool
1 |
|
JedisPoolConfig配置
1 |
|