本文章是在慕课网上学习Redis数据库后,所作的自行总结。
课程链接
Redis学习总结
Redis的数据结构
Key定义的注意点:
- 不要太长,不要超过1024个字节
- 不要过短
- 统一的命名规范
字符串String
- 二进制安全,存入和获取的数据相同
- Value最多可以容纳的数据长度是512M
- 常用命令:
- 赋值
- 取值
- 删除
- 数值增减
- 扩展命令
常用命令 | 含义 |
---|---|
set key value | 设置数值 |
get key | 取值 |
getset key value | 先获取再设置 |
del key | 删除元素 |
incr key | 自增1。若不存在,先初始化为0再自增1。若为字符串等无法自增的元素将执行失败报错误信息。 |
decr key | 自减1。(同上) |
拓展命令 | 含义 |
---|---|
incrby key 5 | 加上自定的数,这里为5。若不存在,则先初始化为0再操作。 |
decrby key 5 | 减去自定的数,这里为5。若不存在,则先初始化为0再操作。 |
append key 5 | 追加(拼接)一个值。若key为3,运行后结果为35。注意不是相加,是拼接。若不存在,则先初始化为0再操作。 |
演示图:
哈希Hash
- 可以看作 string Key 和 string Value 的 map 容器,适合存储值对象的信息,比如用户名密码年龄之类的
- 每一个Hah可以存储4294967295个键值对
- 常用命令
- 赋值
- 取值
- 删除
- 增加数字
- 自学命令
常用命令 | 含义 |
---|---|
hset myhash username jack | 存值 |
hmset myhash2 username rose age 21 | 批量存值 |
hget myhash username | 获取值 |
hmget myhash2 usermane age | 批量获取值 |
hgetall myhash | 获取全部的值 |
hdel myhash2 username age | 删除某个字段。若该字段不存在,返回0 |
del myhash2 | 直接删除整个集合 |
hincrby myhash age 5 | 给集合中的某个元素加 5 。数学意义上的计算。 |
hexists myhash username | 判断集合中的某个元素是否存在。存在为1,否则为0 |
hlen myhash | 获取集合中有几个属性,即多少个元素 |
hkeys myhash | 获取所有属性的名称 |
hvals myhash | 获取所有的值 |
链表List
- 按照插入顺序排序的链表
- 如果在链表的两头进行插入和删除操作,这是非常高效的。但若在中间的话,效率很低
- ArrayList使用数组方式,使用索引去查询非常快。而新增和删除由于需要涉及位移操作,所以比较慢
- LinkedList使用双向链接方式
- 双向链表中增加数据
- 双向链表中删除数据
- 常用命令
- 两端添加
- 查看列表
- 两端弹出
- 获取链表元素个数
- 拓展命令
命令 | 含义 |
---|---|
lpush mylist a b c | 从左侧开始往链表添加数据,当前链表中顺序为 c b a |
rpush mylist2 a b c | 从右侧开始王链表添加数据,当前链表中顺序为 a b c |
lrange mylist 0 5 | 查看列表,从哪开始从哪结束。若为负数则为倒数第几个 |
lrange mylist 0 -1 | 查看整个列表,常用命令 |
lpop mylist | 从左端弹出,若不存在则返回nil。注意弹出后会在链表中删除该元素 |
rpop mylist2 | 从右端弹出 |
len mylist | 查看链表元素个数 |
lpushx mylist x | 仅当参数中的mylist存在的时候,才在头部插入元素。若mylist不存在则返回0,不插入 |
rpush mylist2 y | 与上插入方向相反 |
lrem mylist3 2 3 | 从头开始删除两个3 |
lrem mylist3 -2 1 | 从后往前删除两个1 |
lrem mylist3 0 2 | 删除所有的2 |
lset mylist 3 mmm | 在第3个角标的位置设置一个值为mmm的元素。注意是从0开始数第3个,非界面上序号 |
linsert mylist4 before b 11 | 在第一个值为b的元素之前插入一个11 |
linsert mylist4 after b 11 | 在第一个值为b的元素之后插入一个11 |
rpoplpush mylist5 mylist6 | 将mylist5中尾部的一个元素弹出,在mylist6中的头部插入。该命令经常用于消息队列中使用,可先rpoplpush一个备份链表 |
集合Set
- 和List类型不同,Set集合中不允许出现重复的与元素
- 在服务器端完成多个set之间的聚合计算操作,由于在服务器端完成所以效率非常高,节省大量的网络开销
- Set最大元素数是 4294967295
- 常用命令
- 添加/删除元素
- 获得集合中的元素
- 集合中的差集运算
- 集合中的交集运算
- 集合中的并集运算
- 拓展命令
- 存储Set使用场景
- 跟踪一些唯一性数据,比如访问某一博客的ip地址信息,只需将该博客ip存入Redis中,然后Set就会保证数据的唯一性
- 用于维护数据对象之间的关联关系,利用服务器端聚合操作的特性,比如所有购买某一电子设备的用户的id,被存储在一个指定的Set当中,而购买另外一种电子产品的客户的id,被存储到另一个Set中,若想知道有哪些用户同时购买了两个产品,那么可以通过交集运算实现。
命令 | 含义 |
---|---|
sadd myset a b c | 添加元素 a b c,注意不能重复添加 |
srem myset 1 2 | 删除元素 1 2 |
smembers myset | 查看myset当中有哪些数据,注意元素顺序不为插入的顺序 |
simember myset a | 判断元素a是否在myset中,存在为1,否则为0 |
sdiff mya1 myb1 | 差集运算:以第一个集合mya1为基准查看,第二个集合myb1缺少哪些元素 |
sinter mya2 myb2 | 交集运算:查看两个集合中重复的部分 |
sunion mya3 myb3 | 并集运算:查看两个集合合起来的所有元素,注意去除了重复项 |
拓展命令 | 含义 |
---|---|
scard myset | 查看myset中所含元素个数 |
srandmember myset | 随机返回其中一个元素 |
sdifstore my1 mya1 myb1 | 将mya1和myb1两个集合的差集运算结果保存到my1中,返回my1中的元素个数 |
sinterstore my2 mya2 myb2 | 将mya2和myb2两个集合的交集运算结果保存到my2中,返回my2中的元素个数 |
sunionstore my3 mya3 myb3 | 将mya3和myb3两个集合的并集运算结果保存到my3中,返回my3中的元素个数 |
差集,交集运算理解图(左侧为sdiff mya1 myb1,右侧为sdiff myb1 mya1)
有序集合 Sort Set
- Sort Set与Set相同点:
- 都是字符串的集合
- 都不允许重复的成员出现在一个Set中
- Sort Set与Set区别
- 每一个成员都有一个分数与之关联,通过这个分数对这个成员进行从小到大的排序
- 虽然成员必须是唯一的,但分数是可以重复的
- 在Sort Set中更新删除一个成员都是非常快速的操作,时间复杂度为成员个数的一个对数,即便是中部的函数!!!
- 使用场景:
- 在游戏排名上
- 构建索引数据,比如微博热搜
- 常用命令
- 添加元素
- 获得元素
- 删除元素
- 范围查询
- 拓展命令
常用命令 | 含义 |
---|---|
zadd mysort 70 zs 80 ls 90 ww | 添加元素,注意先分数后成员。返回添加的成员个数,此处为3。若重复添加,更新成员分数,然后返回0 |
zscore mysort zs | 获取某一成员的分数 |
zcard mysort | 获取成员数量 |
zrem mysort tom ww | 删除指定成员(可多个同时删) |
zrang mysort 0 -1 | 展示当前范围里的所有成员,注意指显示成员名,不带分数。顺序为从小到大 |
zrang mysort 0 -1 withscores | 展示当前范围里的所有成员,带分数。顺序为从小到大 |
zrevrange mysort 0 -1 withscores | 展示当前范围里的所有成员,带分数。顺序为从大到小 |
zremrangebyrank mysort mysort 0 4 | 根据范围进行删除,这里为删除前4个 |
zremrangebyscore mysort 80 100 | 根据分数进行删除 |
zrangebyscores mysort 0 100 | 展示指定分数范围内的成员名,不带分数 |
zrangebyscores mysort 0 100 withscores | 展示指定分数范围内的成员名,带分数 |
zrangebyscores mysort 0 100 withscores limit 0 2 | 展示指定分数范围内的成员名,带分数,且只显示指定范围 |
zincrby mysort 3 ls | 对指定成员进行加法运算,这里加上3 |
zcount mysort 80 90 | 显示指定分数范围内的成员个数 |
Keys的通用操作
命令 | 含义 |
---|---|
keys * | 展示所有keys |
key my? | 查看以my开头,后面只跟着一个字符的keys |
del my1 my 2 my3 | 删除指定的key |
exists my1 | 判断指定的key是否存在,存在为1,不存在为0 |
rename company newcompany | 对key进行重命名、 |
expire newcompany 1000 | 设置一个过期时间,成功返回1。注意以秒为单位 |
ttl newcompany | 查看该key所剩的过期时间。注意若该key没设过期时间,将返回-1 |
type mylist | 查看该key的类型 |
flushall | 清空数据库 |
Redis的特性
多数据库
- 一个Redis实例可以包含多个数据库,一个客户端可以指定连接Redis实例的某个数据库
- 一个Redis实例最多提供16个数据库,下标分别是0到15。客户端默认连接第0号数据库,也可以通过select命令选择具体连接哪个数据库。
命令 | 含义 |
---|---|
select 0 | 选择连接第0号数据库 |
move myset 1 | 将当前数据库中的某个key移动到另一个数据库。这里为将myset移动到1号数据库中 |
Redis事务
- 事务中所有命令都会串行化顺序执行。事务执行期间不会再为其他的客户端提供任何的服务,从而保证事务中的所有命令都被原子话执行
- 与关系型数据库的事务相比,再Redis事务中如果某一个命令执行失败,它不会回滚,而是会继续执行余下的命令
- 事务开启之前,如果客户端和服务器之间出现通信故障,导致网络断开,那么它后面所执行的一些语句都不会被服务器执行。但若中断发生在事务开启之后的,那么事务中的所有命令都将被服务器所执行
命令 | 含义 |
---|---|
multi | 开启事务,它后面执行的命令都会被存到命令的队列当中,直到执行exec提交。相当于关系型数据库的START TRANSACTION命令 |
exec | 提交事务。相当于关系型数据库的COMMIT命令 |
discard | 回滚。相当于关系型数据库的ROLLBACK命令 |
Redis的持久化的概述
-
两种持久化方式
- RDB方式,再指定的时间间隔内将内存的数据及快照写入进磁盘
- AOF方式,以日志的形式记录服务器所处理的每一个操作,再Redis服务器启动之初会读取该文件来重新构建数据库,从而保证启动后数据库中的数据是完整的
-
持久化使用方式:
- 单独使用RDB方式,默认支持的不需要去配置
- 单独使用AOF方式
- 不持久化,可通过配置来禁用Redis服务器的持久化的功能,那这样可以认为Redis就是一个缓存的机制
- 同时使用RDB和AOF方式
RDB
- 优势
- 一旦采用这种方式,整个Redis数据库只包含一个文件,这对于文件备份而言是非常完美的。一旦系统出现灾难性的故障,非常容易进行恢复。
- 对于灾难恢复而言,非常轻松的将一个单独的文件压缩后将转移到其他的存储介质上。
- 性能最大化。在开启持久化的时候,唯一需要做的只是分叉出一些进程,之后再由子进程完成持久化的工作,这样可以极大的避免服务器进程进行IO的操作了。相比AOF,如果指数级很大,RDB启动的效率会很高。
- 劣势
- 如果想保证数据的高可用性,最大限度避免数据的丢失,RDB不是很好的选择 。因为系统一定在定时持久化之前出现一些宕机的情况,还没来得及往硬盘上写,数据就丢失了
- 由于RDB通过fork分叉的方式,子进程来协助完成持久化的工作的。如果当数据集非常大的时候,可能会导致服务器停止100毫秒或1秒钟
- 配置
- 查看Redis的配置文件Redis.conf
框内信息为:
- 查看Redis的配置文件Redis.conf
- 每900秒,即15分钟,至少有1个key发生变化,则Down一次内存的快照往硬盘写一次。
- 每300秒,即5分钟,至少有10个key发生变化,则Down一次内存的快照往硬盘写一次。
- 每60秒,即1分钟,至少有10000个key发生变化,则Down一次内存的快照往硬盘写一次。
保存文件的文件名默认为demp.rdb
路径为当前路径上
AOF
- 优势
- 带来更高的数据安全性,提高了三种同步策略,分别是每秒同步,每修改同步和不同步。
- 每秒同步:也是异步完成,效率非常高,相差的是一旦系统出现宕机的现象,那么这一秒钟之内修改的数据会丢失
- 没修改同步:可以视为同步持久化,就每一次发生数据的变化都会被立刻记录到磁盘当中,当然这样效率是最低的,但是是最安全的
- 不同步
- 对于日志文件的写入操作,采用的是append追加的模式,因此在写入过程中出现宕机的现象也不会破坏日志文件中已经存在的内容。如果,在写入了一半数据就出现系统崩溃的问题,也不用担心,在Redis的下一次启动之前,可以通过工具帮助我们解决数据一致性的问题。
- 如果日志过大,Redis可以自动启动重写机制,Redis的append模式不断的将修改的数据写入到老的磁盘文件当中,同时Redis会创建一个新的文件,用来记录此期间产生了那些修改命令被执行了。因此在进行重写切换中可以更好的保证数据的安全性。
- AOF包含一个格式非常清晰易于理解的日志文件,用于记录所有的修改操作。事实上,也可以通过这个文件来完成数据的重建。
- 带来更高的数据安全性,提高了三种同步策略,分别是每秒同步,每修改同步和不同步。
- 劣势
- 对于相同数量的数据集而言,AOF这个文件要比RDB的文件要大一些
- 运行效率慢
- 配置
- 查看Redis的配置文件Redis.conf
默认情况下不打开AOF这种方式,即默认使用RDB方式。若要使用AOF,需要将“appendonly no”改为“appendonly yes”,这个时候会自动产生一个名为“appendonly.aof”的文件(名字可修改)。
同步策略
- 每修改一次就同步
- 每秒同步一次
- 不同步
- 数据库还原
- 打开AOF方式备份,即将“appendonly no”改为“appendonly yes”,然后将同步策略改为appendfsnc always每修改一次就同步
- 执行“./redis-cli shutdown”
- 执行“vim appendonly.aof”,进行修改
- 执行“./redis-server ./redis.conf”,启动Redis
- 执行“./redis-cli”,连接客户端,就还原了