Redis极简入门:纯小白成长为大白

125 阅读19分钟

redis在线入门 : try.redis.io/ redis 中文资料站: www.redis.cn/ www.runoob.com/redis/redis…

Redis 基本介绍

NoSQL

常用的关系型数据库: Oracle,MySQLPostgreSQL 常用的非关系数据库:

  • Redis,MongoDB,ElasticSearch, Hbase

非关系性数据库的特点

键值(Key-Value)存储数据库 这一类数据库主要会使用到一个哈希表,这个表中有一个特定的键和一个指针指向特定的数据。Key/value模型对于IT系统来说的优势在于简单、易部署。但是如果数据库管理员(DBA)只对部分值进行查询或更新的时候,Key/value就显得效率低下了。

文档型数据库 文档型数据库的灵感是来自于Lotus Notes办公软件的,而且它同第一种键值存储相类似。该类型的数据模型是版本化的文档,半结构化的文档以特定的格式存储,比如JSON。文档型数据库可以看作是键值数据库的升级版,允许之间嵌套键值,在处理网页等复杂数据时,文档型数据库比传统键值数据库的查询效率更高。如:CouchDB, MongoDb. 国内也有文档型数据库SequoiaDB,已经开源。

redis下载:这是官方推荐的win下载方式 转存失败,建议直接上传图片文件

radis 有哪些特点?

IO是毫秒级别、内存是纳秒级别。不是一个数量级的速度比较

特点:

  • 满足数据高并发读写的性能要求,因为直接是内存中进行读写的,类似于CPU的分级缓存机制
  • 单线程操作,每个操作都是原子操作,没有并发相关问题(redis6)
  • 对海量数据的高效率存储和访问
  • 对数据的可拓展性和高可用性
  • 6379端口

为什么是这样设计的?

为什么是单线程:因为CPU内部时间片之间相互切换的成本太高了。当未来CPU发展之后,极大降低时间片的切换成本后,有变回单线程的可能性

Redis定位是缓存,满足数据高并发读写的性能要求;减轻对数据库存储与访问压力

  • 当我们要用到缓存,先思考是否有需要使用
  • 在实际使用中,一些请求直接打到缓存上,能够从缓存中获取到数据,就不用到数据库或者磁盘中重新获取,减轻了数据库存储与访问压力
  • 作为缓存,例如,相同的筛选条件,我们可以存储好图片的Id,下次相同的筛选条件进来之后,返回一样的图片id,而不是重新到MySQL数据库中找

常用的数据类型

常用的数据类型

常用的数据类型有5个:使用字符串存储的String类型,代表对象的哈希类型,集合的 set 类型,有序序列的 sorted set 类型,列表(它的底层实现是双向队列)。

常用:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)

string

命令格式功能案例
set key value将key-value缓存redis中set name dafei
get key从redis中获取key对应value值get name
incr key将key对应value值 + 1incr age
decr key将key对应value值-1decr age
setex key seconds value将key-value缓存到redis中,seconds 秒后失效setex sex 10 man
ttl key查看key存活时间ttl sex
del key从redis中删除keydel name
setnx key value如果key已经存,不做任何操作,如果key不存,直接添加setnx name xiaofei

使用场景

  • 缓存查询结果,降低数据库的访问压力。例如搜索某个东西的时候,我们可以把查询条件加上固定 id 作为 key ,查询的结果,作为 value。
  • 缓存视频播放数量,使用 redis 作为视频播放数的计数器
  • 共享 session
    • 当我们的服务器做了负载均衡,我们的请求就会发送到不同的服务器上进行处理
    • 当我们的 a 服务器承受的访问压力较大时,此时负载均衡可能将新进来的访问给到 b 服务器。这个时候,用户刷新一次再进行访问,就可能需要重新登录
    • 为了避免这种不正常的情况,我们可以用 redis 将用户的 session 集中管理。在这种模式下,我们只需要保证 redis 的高可用和拓展性就可以保证每次自己的登录信息都是一致的。每次获取用户更新或者查询的信息时,统一从 redis 中获取即可。

Hash类型

命令格式功能案例
hset key field value将field value对缓存到redis中hash中,键值为keyhset user name dafei
hget key field从key对应hash列表中获取field字段hget user name
hexists key field判断key对应的hash列表是否存在 field字段hexists user age
hdel key field删除key对应hash列表中field字段hdel user age
hincrby key field increment给key对应hash列表中field字段 + incrementhincrby user age 10
hlen key查看key对应的hash列表field的数量hlen user
hkeys key获取key对应的hash列表所有的field值hkeys user
hvals key获取key对应的hash列表所有的field对应的value值kvals user
hgetall key获取key对应的hash列表中所有的field及其对应的value值hgetall user

使用场景

  • 跟上面的字符串存储的类型是类似的,但是这种方式更利于内部信息的更改操作。

  • 对于登录信息的缓存有两种方案,

    • 第一种方案是将对象的信息转为 json 格式的字符串存在 redis,这就是 string 的字符串的做法。
    • 第二种方式是将 user 对象转换为哈希对象存储。在 redis 里面,这种方式更侧重于修改、更改信息,但是查询操作相对来说更加麻烦

List类型

我们从操作 list 命令中就可以看到,它里面有 push 和 pop 命令,猜也能猜到,它就是一个队列。

但实际使用跟猜测的还是有一点出入的。当整个列表的元素数量较小,或者是元素的体积较小时,它会采用一种紧凑的结构,叫做压缩列表。当整个列表的元素较大以及数量较多时,它会采用另外一种数据结构,叫做双向链表。

  • 这样做的好处有很多,当整个列表的元素较小,数量较少时,我们采用压缩列表就可以很大的程度上节省空间。
  • 压缩列表的底层实现是:数字加元素内容(非常紧凑的实现方式)

常用的命令

命令格式功能案例
rpush key value从右边往key集合中添加value值rpush hobby java
lrange key start stop从左边开始列表key集合,从start位置开始,stop位置结束lrange hobby 0 -1
lpush key value从左边往key集合中添加value值lpush hobby c++
lpop key弹出key集合中最左边的数据lpop hobby
rpop key弹出key集合中最右边的数据rpop hobby
llen key获取列表长度llen hooby
  • 可以用来存储用户收藏文章的列表,以及关注人列表等等。一些比较多增删改的地方

Set类型

Set集合是String类型的无序集合,set是通过HashTable实现的,对集合我们可以取交集、并集、差集。

常用的命令

命令格式功能案例
sadd key members [....]往key 集合中添加member元素sadd myset a b c
smembers key遍历key集合中所有的元素smembers myset
srem key members [....]删除key集合中members元素srem myset a
spop key count从key集合中随机弹出count个元素spop myset 1
  • 去重(set 集合自带的特性)
  • 抽奖(pop随机抽取)

Sorted set 类型

Sorted set 也称Zset类型,是一种具有排序效果的set集合。它跟set集合一样也是 string 类型元素的集合,且不允许重复的成员。并且要求每个元素都会关联一个double 类型的分数。后续可以通过分数来为集合中的成员进行从小到大的排序。

Sorted set集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。 集合中最大的成员数为 232 - 1 (4294967295, 每个集合可存储40多亿个成员)。

命令格式功能案例
zadd key score member往key集合中添加member元素,分数为scorezadd players 100 a
zincrby key increment member将key集合中的member元素 分数 + incrementzadd players 100 a
zrange key start stop [withscores]将key集合中的元素按分数升序排列 [显式分数]zrange players 0 -1 withscores
zrevrange key start stop [withscores]将key集合中的元素按分数降序排列 [显式分数]zrevrange players 0 -1 withscores
zrank key member返回member元素在key结合中的正序排名zrank players a
zrevrank key member返回member元素在key结合中的倒序排名zrevrank players a
zcard key返回key集合元素个数zcard players
  • 排行榜:有序集合经典使用场景。例如视频网站需要对用户上传的视频做排行榜,榜单维护可能是多方面:按照时间、按照播放量、按照获得的赞数等。
    • 按照新增时间进行排序、按照操作的新增时间对关注人列表进行排序
127.0.0.1:6379> help set

  SET key value [expiration EX seconds|PX milliseconds] [NX|XX]
  summary: Set the string value of a key
  since: 1.0.0
  group: string

全局命令

全局命令针对的是所有的key,大部分用来做运维,做管理的

常用的全局key

命令格式功能案例
keys pattern按照pattern 匹配规则,列表redis中所有的keykeys xxx:*
exists key判断key是否存在exists name
expire key seconds给key设置过期时间,超时:secondsexpire name 10
persist key取消key过期时间persist name
select index切换数据库,默认是第0个,共有【0,15】个select 0
move key db从当前数据库将key移动到指定db库move name 1
randomkey随机返回一个keyrandomkey
rename key newkey将key改名为newkeyrename name newname
echo message打印message信息echo message
dbsize查看key个数dbsize
info查看redis数据库信息info
config get *查看所有redis配置信息config get *
flushdb清空当前数据库flushdb
flushall清空所有数据库flushall

理论知识

事务

Redis事务可以理解为一个打包的批量执行脚本,但批量指令并非原子化的操作,中间某条指令的失败不会导致前面已做指令的回滚,也不会造成后续的指令不做。

redis 127.0.0.1:6379> MULTI
OK

redis 127.0.0.1:6379> SET book-name "Mastering C++ in 21 days"
QUEUED

redis 127.0.0.1:6379> GET book-name
QUEUED

redis 127.0.0.1:6379> SADD tag "C++" "Programming" "Mastering Series"
QUEUED

redis 127.0.0.1:6379> SMEMBERS tag
QUEUED

redis 127.0.0.1:6379> EXEC
1) OK
2) "Mastering C++ in 21 days"
3) (integer) 3
4) 1) "Mastering Series"
   2) "C++"
   3) "Programming"
  1. redis 的事务类似于 bash 的指令集,仅代表批量操作
  2. 批量操作一旦开始,其他现成的操作不能在中间插入
  3. 批量操作一旦开始,中间有错误,不会回滚,会继续向下执行

持久化

Redis持久化机制目前以后3种,分别为:

1>快照方式(RDB, Redis DataBase)

2>文件追加方式(AOF, Append Only File)

3>混合持久化方式(Redis4版本之后)

RDB

第一种快照方式就是 Redis DataBase来存储数据,

Snapshotting(快照)默认方式,将内存数据中以快照的方式写入到二进制文件中,默认为dump.rdb。触发RDB持久化过程分手动触发与自动触发。

  1. Redis 主线程:主线程负责处理客户端发送的命令请求,执行数据操作,处理持久化,以及其他与 Redis 服务器相关的任务。主线程不会因为执行持久化操作而自行阻塞,因为 Redis 使用了异步的持久化机制来确保主线程的高性能和可用性。
  2. BGSAVE 执行时机:BGSAVE 操作的执行时机通常是在满足一定条件下触发的,例如当服务器的内存使用量达到一定阈值,或者根据配置文件中设置的自动持久化策略。当满足了执行条件后,Redis 会自动触发 BGSAVE 操作。
  3. BGSAVE 子线程:当执行 BGSAVE 操作时,Redis 会创建一个子进程来执行持久化操作。这个子进程会复制主进程的内存数据,并在内存中进行持久化操作,然后将持久化后的数据写入到磁盘上的持久化文件中。完成持久化操作后,子进程会自行销毁,不会影响主线程的正常运行。
  4. 内存数据的持久化:在 BGSAVE 操作中,子进程会将主线程的内存数据复制一份,并在内存中进行持久化操作,然后将持久化后的数据写入到磁盘上的持久化文件中。这样可以确保在持久化操作期间,主线程仍然可以继续处理客户端请求,保持高性能和可用性。

AOF

第二种方式AOF, Append Only File

可以将 AOF 持久化方式理解为备份数据和还原数据的过程:

  1. 写操作(备份数据): 当客户端对 Redis 执行写操作时,例如设置键值对、删除键等,Redis 将这些写操作以追加的方式记录到 AOF 文件中。这个过程可以看作是备份数据的过程,将内存中的数据持久化到磁盘上的 AOF 文件中。
  2. 读操作(还原数据): 当 Redis 服务器启动时,或者执行 BGREWRITEAOF 命令时,Redis 会读取 AOF 文件,并逐行执行其中的命令来还原数据。这个过程可以看作是从 AOF 文件中读取数据,并将其加载到内存中,从而恢复数据到 Redis 数据库中。

对 AOF 的理解

  • 写操作:AOF(Append Only File)是 Redis 的一种持久化方式。它将客户端的写操作以追加的方式记录到一个文本文件中。
  • 读操作:redis 服务器启动的时候,会读取 AOF文件到内存中,并逐行执行其中的 redis 命令来还原数据
  • 优势
    • 对 CPU 和内存友好,相较于 RDB,不需要那么多的额外性能来执行持久化操作
    • 定期记录客户端的写操作到文本文件中(不是每次都写到磁盘上,而是有一个缓冲区),确保数据的完整性和一致性
  • 劣势
    • AOF 文件大小通常比较大。
    • 可能存在一些冗余操作,导致在数据恢复时可能较慢。
    • 【优化冗余】AOF 文件重写(AOF rewrite):定期对 AOF 文件进行重写,以减少文件的大小和冗余操作,提高数据恢复的运行效率。

RDB+AOF

Redis 4.0 之后推出的 RDB-AOF 混合持久化模式,其作为默认配置来使用

  1. 全量备份(RDB): 当执行备份操作时,Redis 首先会将当前所有的数据以全量备份的方式保存到 RDB 文件中。这个全量备份包含了当前数据的完整快照,可以用于在 Redis 重启时快速恢复数据。
  2. 增量备份(AOF): 紧接着,Redis 会将后续的客户端写操作以增量备份的方式记录在 AOF 文件中。这个增量备份记录了对数据的修改操作,可以保证即使在 Redis 重启时发生故障,也能够恢复到最后一次持久化的状态。
  3. 恢复过程: 在 Redis 重启时,先使用 RDB 文件进行快速恢复数据,然后再重新执行 AOF 文件中记录的操作命令,来完成数据的完整恢复。这样一来,既能够保证 Redis 重启的速度,又能够降低数据丢失的风险。

混合持久化模式结合了 RDB 和 AOF 的优点,为 Redis 提供了更为可靠的数据持久化和恢复机制。这种模式在实际应用中被广泛采用,以确保数据的安全和可靠性。

讲了这么多,但最终在生产条件下,推荐的使用方式是混合持久化模式,也就是 Redis 4.0 版本之后提供的默认持久化方式

内存淘汰机制

  1. LRU (Least Recently Used):最近最少使用算法。根据数据最近被访问的时间来决定哪些数据将被淘汰。当内存空间不足时,将优先淘汰最近最少被访问的数据。
  2. LFU (Least Frequently Used):最不经常使用算法。根据数据被访问的频率来决定哪些数据将被淘汰。当内存空间不足时,将优先淘汰访问频率最低的数据。
  3. Random:随机删除算法。随机选择一些数据项进行删除。这种方法简单粗暴,但无法保证删除的数据是最不重要的。
  4. TTL (Time To Live):生存时间算法。通过设置数据的过期时间来自动淘汰过期的数据。当数据的过期时间到达时,Redis 会自动将其删除。
  5. Maxmemory Policy:根据策略选择淘汰数据。除了以上几种具体的算法外,Redis 还提供了一种灵活的淘汰策略,允许用户根据具体的需求选择淘汰算法。常见的策略包括:
    • volatile-lru:只对设置了过期时间的键使用 LRU 算法进行淘汰。
    • volatile-ttl:只对设置了过期时间的键进行淘汰,删除剩余时间较短的键。
    • volatile-random:只对设置了过期时间的键进行随机淘汰。
    • allkeys-lru:对所有键使用 LRU 算法进行淘汰。
    • allkeys-random:对所有键进行随机淘汰。
    • noeviction:不淘汰任何数据,当内存不足时,新增操作会报错,Redis 默认内存淘汰策略

volatile 意味着变化

在 Redis 中,"volatile" 键表示具有过期时间的键,其 TTL(Time To Live)属性会随着时间的推移而变化。

  • allkeys-xxx 表示从所有的键值中淘汰数据,而 volatile-xxx 表示从设置了过期键的键值中淘汰数据。
127.0.0.1:6379> config get maxmemory
1) "maxmemory"
2) "0"
127.0.0.1:6379> config get maxmemory-policy
1) "maxmemory-policy"
2) "noeviction"
127.0.0.1:6379> config set maxmemory-policy volatile-ttl
OK

怎么用?

操作技巧:spring-data-redis api方法名是redis命令的全称

思考的点

  1. 该功能点是否需要用缓存?
  2. 直接使用一个 map 能否解决问题?
  3. 设计 redis 的key value
    • 需要排序吗?
    • 不需要排序,推荐使用 string,利用 json object 完成数据存储

整体总结

redis概念,定位,优点,缺点,运用

  • redis 定位是一个高性能的缓存,可以帮助减轻数据库的访问压力
  • 优点是速度快!能够满足高性能高并发下的性能要求,显著地降低数据库的存储与访问压力
  • 缺点是不支持 acid 的特性,缺少一些关系性的维护

常用的数据类型,各种命令

我们平常比较常用的数据类型5个,第一个是 string,string 是最简单并且最通用的数据类型,当然,这也是我们平常工作中最常用的数据类型。它可以以文本方式存储字符串、整数以及浮点型的数据,甚至 object 对象也可以存储。第2个是哈希,哈希是用来存储某个特定对象的,类似于字典或者 map,可以将多个键子对存储在一个键里面,适合用来存储对象的属性。第3个是 set,set 就是无序集,它可以用来帮助我们完成去重或者随机抽取的操作。第4个是 sorted set,也叫做 zset,这个集合是根据 score 属性去进行排序的,当我们需要借助 redis 去帮我们完成自动排序,那么我们就需要用到 sorted set。第5个是 list list,它的实现方式有两种,第一个是双向链表,第2个是压缩列表。我们使用的时候只需要理解它是一个队列,并且支持从两端进行元素的插入和删除(仅提供 pop 以及 push api,类似于队列或栈,只能对两端的元素进行操作)

  • 这里需要注意,在List类型中。redis 它这样的设计是为了保证整体的操作性能,并且我们常用的操作也是仅在数据的头和尾进行增删操作,而对中间元素的增删操作比较少见。所以 redis 更倾向于优化对数据的头尾元素的操作,是为了提高整体的性能效率
  • 很多命令我们不知道的可以直接从 redis 里面拿到,其实跟我们 api 里面的操作是非常类似的

redis 全局命令

redis-cli -h 127.0.0.1

redis-cli -h 127.0.0.1 -a test123
dbsize

keys *
keys aa?

del key

expire key 5
ttl key
说明: >=0:表示剩余的过期时间 -1:不存在过期时间(持久存在) -2:找不到这个键,过期了或者不存在

redis 安全与事务

Linux系统

编辑 redis.conf文件,找到下面进行保存修改

  • 在配置文件中,将 requirepass 后面的值设置为您希望设置的密码。例如:requirepass 自定义密码

重启Redis服务,访问时,使用带密码的命令:

  • redis-cli -a 自定义密码

  • redis-cli -h your_redis_host -p your_redis_port -a your_password 
    

否则会提示: (error)NOAUTH Authentication required.

Window系统

跟Linux系统一样,区别是,window系统的文件是

redis.window-service.config