Redis学习笔记(一)
1.Redis简介
说到数据库,相信我们大家都了解,说的这里呢,要讲讲数据库里的分类。一类是关系型数据库(例如:MySQL、Oracle),另外一类就是非关系型数据库(也称NoSQL数据库),而我们今天要将Redis就是NoSQL数据库的典型代表。
首先,讲讲为何叫NoSQL数据库呢?因为它是不用写SQL语句的数据库,而是以一种key-value形式进行数据存储的,并且它是完全基于内存进行操作的,因此性能非常好。近些年来,随着内存技术的不断发展,内存变得越来越便宜,所以,Redis的风靡势必是个趋势
其次,Redis作为NoSQL数据库的代表,是近些年来发展最好,也是被各大公司所青睐的,它有以下三个特点:
- 支持数据的持久化(RDB、AOF两种持久化方式)
- 支持五种复杂的数据结构(String、List、Set、ZSet、Hash)
- 支持集群和数据的备份,即master-slave模式的数据备份
除此之外它还有很多其它NoSQL数据库所没有的优势:
- 业界性能公认最高,每秒钟读写次数可达10W+
- 丰富的数据类型
- 操作都是原子性
- 支持设置Key失效多种方案
2.五种数据类型的简单使用
首先需要声明,Redis的key只支持字符串类型,不支持其他类型
以下演示都是在:Try Redis这个网站在线调试的,搜索相关Redis命令可到:Redis 命令参考
-
String:最简单也是最基础的一种key-value
现实生活中使用场景:微博数,粉丝数等
> set hk1 "hhhh" OK > get hk1 //取数据 "hhhh"
-
List:底层是使用双向链表实现的,可以存放多个value
现实生活中使用场景:微博的关注列表,粉丝列表,消息列表等
> lpush hk2 "你" (integer) 1 > lpush hk2 好 (integer) 2 > lpush hk2 吗? (integer) 3 > lrange hk2 0 3 //取数据 1) "吗?" 2) "好" 3) "你"
-
Set:保证数据的不重复(去重),还可以提供一系列的交集、并集、差集的命令
现实生活中使用场景:比如在微博中,可以将每个用户的所以关注人存到一个集合,所以粉丝也存到一个集合。那么久可以很方便的实现:共同关注、共同粉丝
> sadd hk3 你 (integer) 1 > sadd hk3 好 (integer) 1 > sadd hk3 好 (integer) 0 > smembers hk3 //取数据 1) "好" 2) "你"
-
ZSet:在Set的基础上,保证了有序性
现实生活中使用场景:实时排行榜信息
> zadd hk4 1 redis (integer) 1 > zadd hk4 2 mongodb (integer) 1 > zadd hk4 3 mysql (integer) 1 > zadd hk4 4 mysql (integer) 0 > ZRANGE hk4 0 4 //取数据 1) "redis" 2) "mongodb" 3) "mysql"
-
Hash:使用哈希数据结构实现,特别适合存储对象
现实生活中使用场景:存储用户信息,商品信息
> hmset hk5 name "令狐冲" skills "独孤九剑+吸星大法" wife "任盈盈" hobby "喝酒" OK > HGETALL hk5 //取对象 1) "name" 2) "令狐冲" 3) "skills" 4) "独孤九剑+吸星大法" 5) "wife" 6) "任盈盈" 7) "hobby" 8) "喝酒"
3.过期时间和策略
通常,我们的内存是十分有限的,像我的笔记本加了个4G内存条,也不过才8G而已。所以,干掉那些不用的数据是十分有必要的
- 设置键的生存时间可以通过
EXPIRE
或者PEXPIRE
命令。 - 设置键的过期时间可以通过
EXPIREAT
或者PEXPIREAT
命令。
既然有设置过期(生存)时间的命令,那肯定也有移除过期时间,查看剩余生存时间的命令了:
- PERSIST(移除过期时间)
- TTL(Time To Live)返回剩余生存时间,以秒为单位
- PTTL以毫秒为单位返回键的剩余生存时间
键的过期策略有三种
- 定时删除(对内存友好,对CPU不友好)
- 到时间点就把所有过期的键删除
- 惰性删除(对CPU极度友好,对内存极度不友好)
- 每次取键时,都判断一下是否过期,若过期就删除
- 定期删除(折中)
- 每隔一段时间去删除过期键,限制删除的执行时长和频率
Redis采用的是惰性删除+定期删除两种策略,所以说,在Redis里边如果过期键到了过期的时间了,未必被立马删除的!
4.内存淘汰机制
当大量失效key堆积在内存当中,内存容量耗尽,这个时候我们可以通过设置内存的最大使用容量,当内存超过最大值时,就实施数据淘汰策略,一共分为6种,如下所示:
策略 | 描述 |
---|---|
volatile-lru | 从已设置过期时间的数据集中挑选最近最少使用的数据淘汰 |
volatile-ttl | 从已设置过期时间的数据集中挑选将要过期的数据淘汰 |
volatile-random | 从已设置过期时间的数据集中任意选择数据淘汰 |
allkeys-lru | 当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的key(最常用) |
allkeys-random | 从数据集中任意选择数据淘汰 |
no-eviction | 禁止驱逐数据,也就是说当内存不足以容纳新写入数据时,新写入操作会报错。 |
这边还有个很经典的面试题,大家可以思考思考
MySQL里有2000w数据,Redis中只存20w的数据,如何保证Redis中的数据都是热点数据?
5.持久化机制
NoSQL数据库的最大特点就是完全基于内存,所以,这也带来了一个安全问题----万一发生意外情况,数据怎么办?不必担心,作为Redis,人家已经有了自动持久化机制了,分为两种,我们就来聊一聊:
-
RDB:在指定时间间隔之内将内存中的数据集写入到磁盘中,实际上是创建了一个子进程,里面数据保持和内存中的数据一模一样,待出发持久机制成功后,用二进制压缩文件,命名为.rdb文件,存放到磁盘中,是Redis默认采用的持久化方式
在redis.conf配置文件中,默认有以下配置:
save 900 1 #在900秒(15分钟)之后,如果至少有1个key发生变化,Redis就会自动触发BGSAVE命令创建快照。 save 300 10 #在300秒(5分钟)之后,如果至少有10个key发生变化,Redis就会自动触发BGSAVE命令创建快照。 save 60 10000 #在60秒(1分钟)之后,如果至少有10000个key发生变化,Redis就会自动触发BGSAVE命令建快照
- 优点:RDB是个非常紧凑的文件,它是按时间段来备份数据集的,比如说,你可以在最近的 24 小时内,每小时备份一次 RDB 文件,并且在每个月的每一天,也备份一个 RDB 文件,所以,很适合于灾难恢复
- 缺点:如果需要尽量避免在服务器故障时丢失数据,那么 RDB 不适合了,因为它会丢失前一次快照的数据,这个数据量取决于你的项目大小
-
AOF(Append Only File):保存Redis服务器所执行的写命令来记录数据库的数据
Redis默认未开启AOF持久化,可以在redis.conf文件中配置
appendonly yes
在开启AOF持久化之后,每当Redis进行一次写操作后,就会将该命令写到磁盘的AOF文件中,位置和RDB文件一样,这边可以配置三种不同的AOF持久化方式:
appendfsync always #每次有数据修改发生时都会写入AOF文件,这样会严重降低Redis的速度 appendfsync everysec #每秒钟同步一次,显示地将多个写命令同步到硬盘(最常用) appendfsync no #让操作系统决定何时进行同步
- 优点:安全级别高,可以通过设置fsync策略,每一秒钟写入到AOF文件中,这样,就算服务器宕机,Redis也只会丢失前一秒的数据
- 缺点:AOF文件一般所占大小比RDB文件要大,而且,由于设置fsync策略,AOF持久化速度上会比RDB要慢
-
在Redis 4.0之后,支持RDB和AOF混合持久化机制(默认关闭,可以通过配置项 aof-use-rdb-preamble 开启)
6.总结
Redis是高级程序员必备技能,在应届生面试者,也是常问的技术点,如果你掌握得比他人好,你就有优势,所以说,还是得好好学一下,最后,推荐点干货: