超详细Redis总结(一)

redis现在是火的一塌糊涂,不知道redis怎么能行,各个云都提供了对redis的支持,如阿里云等。

什么是Redis

Redis 是一个开源的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。 支持多种类型的数据结构,如string(字符串)、hash(哈希)、list(列表)、set(集合)、zset(sorted set:有序集合)。

首先redis是将数据保存到内存中,都知道内存断电后数据就没了,所以,如果redis不做一些处理,他所保存的数据将消失。这里的数据存储类似于java中的map,对redis而言,key都是字符串,而value则是上述中的多种数据类型。

而redis大部分用来做缓存,什么是缓存呢?也就是把数据库中的数据暂时放入到redis中,客户端请求时如果缓存中有,则直接拿出来返回,如果没有则去数据库中查找,并放入redis,这样响应速度会有提升,也给数据库减轻压力。

消息中间节则可以简单理解为多个应用之间进行数据交互,如系统A向Redis订阅了主题"momo",而系统B向这个主题"momo"中发送消息,此时系统A就能收到这个消息(这是个订阅发布模型)。但是Redis貌似也不推荐作用于消息中间件,就像用Java去写桌面程序一样,而推荐使用RabbitMQ、ActiveMQ等进行处理。

诞生起因

无非就是对当前使用的东西不满意,或者这个东西无法满足自己需求,所以自行开发新的。在2008年,意大利的一家创业公司Merzia推出了一款基于MySQL的网站实时统计系统LLOOGG,然而没过多久该公司的创始人 Salvatore Sanfilippo便 对MySQL的性能感到失望,于是他决定亲自为LLOOGG量身定做一个数据库,并于2009年开发完成,这个数据库就是Redis。 不过Salvatore Sanfilippo并不满足只将Redis用于LLOOGG这一款产品,而是希望更多的人使用它,于是在同一年Salvatore Sanfilippo将Redis开源发布,并开始和Redis的另一名主要的代码贡献者Pieter Noordhuis一起继续着Redis的开发,直到今天。
Salvatore Sanfilippo自己也没有想到,短短的几年时间,Redis就拥有了庞大的用户群体。Hacker News在2012年发布了一份数据库的使用情况调查,结果显示有近12%的公司在使用Redis。国内如新浪微博、街旁网、知乎网,国外如GitHub、Stack Overflow、Flickr等都是Redis的用户。

大公司当然少不了支持,VMware公司从2010年开始赞助Redis的开发, Salvatore Sanfilippo和Pieter Noordhuis也分别在3月和5月加入VMware,全职开发Redis。

大佬就是大佬,永远是那么不经意间。

Redis大小限制

参考:https://redis.io/topics/data-types-intro、https://redis.io/topics/data-types
字符串value的最大长度为512 MB。
在这里插入图片描述
List的元素个数最多为2^32-1个,也就是4294967295个。同样Set、Hash也是一样。
在这里插入图片描述
Key 大小也是512MB
在这里插入图片描述

客户端命令

redis分为客户端、服务端,服务端用来保存数据,而客户端通过redis的通信协议+一堆命令和服务端进行交互,由于开源,也有一堆的客户端实现(Java、C等众多语言)。java中比较推荐的是jedis和redisson,有能力的也可以自研。也有可视化的工具。

这些命令构成了对上述数据类型的操作,可以在以下网址进行学习
1.http://redisdoc.com
2.https://www.runoob.com/redis/redis-commands.html
3.http://doc.redisfans.com/index.html
4.https://www.redis.net.cn/tutorial/3501.html

Redis通信协议

Redis默认通过6379端口监听,所以,创建一个Socket,怼到此端口就可以了,客户端向服务端发送数据时,以\n\r结束,服务响应时,通过不同前缀,来区分数据类型,所以,怼成功后,不断按照Redis命令规范输出到IO流,输出完开始按照Redis应答规范解析就可以了。

Redis定义了5种应答前缀,分别为+、-、:、$、*,通过IO流拿到数据后,需要判断是什么类型,转化成不同Java对象,比如String、Integer、List
在这里插入图片描述
可以参考以前的博客https://mp.weixin.qq.com/s/7K0U4qds5flAUfemviVb4A

redis到底是单线程还是多线程?

很多人以为,高性能的服务器是多线程来实现的,其实不然,对redis是而言,是单线程的,这是因为线程上下文切换需要花费一定时间。上下文切换意思是从当前执行任务切换到另一个任务执行的过程。但是,为了确保下次能从正确的位置继续执行,在切换之前,会保存上一个任务的状态。但过多的上下文切换,会把CPU时间消耗在寄存器、内核栈以及虚拟内存等数据的保存和恢复上,从而缩短进程真正运行的时间,导致系统的整体性能下降。

而redis采用单线程的话,就可以避免上下文切换等,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗。 这也是redis快的一个原因。

但是这里的单线程是指网络请求模块使用了一个线程,也就是一个线程处理所有网络请求,其他模块还是多线程。

那redis又如何让一个线程处理n个请求呢?答案是采用NIO多路复用技术实现,多路是指多个网络连接,复用指复用同一个线程。在java中可以使用SocketChannel、Selector等实现。

订阅/发布

redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息。
这类似于微信的公众号,客户可以订阅任意数量的公众号,当公众号有新文章后,订阅的人都会收到,redis 客户端也可以订阅任意数量的主题。

订阅者通过SUBSCRIBE 来订阅一个或多个主题,发布者用PUBLISH来向主题发送消息。这里的主题可以比作一个挂载点,众多客户端将自己挂到上面,发布者向指定挂载点发送消息时,挂在上面的客户端都能收到消息。
在这里插入图片描述

事物

Redis 事务可以一次执行多个命令, 并且带有这三个重要的保证

  1. 批量操作在发送 EXEC 命令前被放入队列缓存。
  2. 收到 EXEC 命令后进入事务执行,事务中任意命令执行失败,其余的命令依然被执行
  3. 事务执行过程,其他客户端提交的命令请求不会插入到事务执行命令序列中。

其中MULTI、EXEC、DISCARD 和WATCH、UNWATCH命令是对Redis事务的操作,其中MULTI声明事务开始,后续命令将排队按顺序等待EXEC执行。DISCARD是取消事务。WATCH和UNWATCH是监视一个或多个key和清除事务监控的键。

先说第一条意思,也就是当输入MULTI开启事物后,后续所有redis正常操作命令会按照先进先出(FIFO)的顺序出入列,并返回QUEUED,直到输入EXEC为止。正常操作是指按照redis命令规范、格式来操作,否则这个过程中会报错,事物将退出。
在这里插入图片描述
MULTI不能嵌套,否则报错,但是不会影响事物状态。
在这里插入图片描述
第二条意思是,redis事物在使用EXEC开始执行后,即使有n条命令失败,剩余的也都会执行,如下图,incr在操作非数字时候会报错,但是报错后紧跟着的命令还是会执行,直到所有命令都完成。
在这里插入图片描述
第三见名之意,就不说了。

那为什么redis不支持回滚呢?大概是因为作者觉得失败的命令是由编程错误锁造成的,而这些错误应该在开发的过程中就被发现,所有上述说的当事物开启后,如果有错误的语法输入,事物则会关闭。
并且没有事物回滚,redis内部能简单快速。

缓存击穿

缓存击穿意思是在某个时间,redis中的某一个数据在抗这非常大的请求,但是下一秒数据却过期了,这一堆请求走向数据库。

解决办法可以通过增加互斥锁,当第一个线程拿到锁后请求数据库,并设置到redis中,其他线程后续直接从redis中取。

缓存穿透

缓存穿透是指redis中没有此条数据,便走向数据库,而数据库中也没有这条数据。
比如自增id,如果查询小于1的id,肯定不存在。当面临非常大的请求时,数据库也会受不了。

可以通过参数校验,明知这个数据在数据库中一定不存在,则直接返回,或者通过布隆过滤器,布隆过滤器实际上是一个很长的二进制向量和一系列随机映射函数,也就是里面存的不是1就是0,布隆过滤器可以用于检索一个元素是否在一个集合中(但这不代表一定存在)。

新建一个布隆过滤器,默认张这个样子。
在这里插入图片描述
此时如果要添加一个数据在里面,就需要用到多个不同的hash函数,计算出数据位置,并把对应位置置为1。例如H,通过三个hash函数计算出为1、2、6,如图。
在这里插入图片描述
接着添加一个X,通过三个hash计算出为3、4、7,如图。
在这里插入图片描述
现在要判断某个数据是否存在,例如L,通过三个hash计算出位置为1、3、8,而上图位置1、3都为bit 1,但是8为0,则表示L一定不存在,但是如果计算出位置为1、3、7,而不巧这几位都为1,但是L确确实实不存在,所以说,布隆过滤器能保证数据一定不存在,而不保证数据一定存在。

一般情况下布隆过滤器不能删除,这是因为每一位可能被多个数据所共享,如果删除其中一位,会影响其他数据。

可以使用Google提供的guava实现。

<dependency>
  <groupId>com.google.guava</groupId>
  <artifactId>guava</artifactId>
  <version>19.0</version>          
</dependency>

缓存雪崩

缓存雪崩是指redis中的数据在某一时刻大面积失效,所有的数据又都走向数据库。导致数据库、CPU和内存负载过高。可以给缓存设置一个随机值过期时间,让每个key的过期时间分布开来。

持久化

Redis有两种方式持久化,分别是RDB、AOF
RDB是一种快照存储持久化方式,就是将某一时刻的内存数据保存到硬盘中,默认保存的文件名为dump.rdb,而在Redis服务器启动时,会重新加载dump.rdb文件中的的数据到内存当中。客户端可以通过向Redis服务器发送save或bgsave命令让服务器生成rdb文件,这两个命令的区别是save是同步阻塞,而 bgsave 是非阻塞,或者通过服务器配置文件指定触发RDB条件。也就是在配置文件redis.conf中增加以下配置。

# 900s内至少达到一条写命令
save 900 1
# 300s内至少达到10条写命令
save 300 10
# 60s内至少达到10000条写命令
save 60 10000

而AOF持久化方式会记录客户端对服务器的每一次写操作命令,并将这些写操作以Redis协议追加到后缀名为aof文件末尾,在Redis服务器重启时,会加载并运行aof文件中的命令,从而起到恢复数据的目的。
开启AOF功能需要配置:appendonly yes,默认不开启。

# 默认关闭若要开启将no改为yes
appendonly no
# append文件的名字
appendfilename "appendonly.aof"
# AOF文件的写入方式
# always一旦缓存区内容发生变化就写入AOF文件中
appendfsync always
# everysec 每个一秒将缓存区内容写入文件 默认开启的写入方式
appendfsync everysec
# 将写入文件的操作交由操作系统决定
appendfsync no
# 当AOF文件大小的增长率大于该配置项时自动开启重写(这里指超过原大小的100%)。
auto-aof-rewrite-percentage 100
# 当AOF文件大小大于该配置项时自动开启重写
auto-aof-rewrite-min-size 64mb

RDB优点:
1、RDB是一个快照文件,数据很紧凑,它保存了 Redis 在某个时间点上的数据集,体积比较小。
2、RDB 适合用于灾难恢复,因为它只有一个文件,而且体积小,方便拷贝。
3、RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快。

RDB缺点:
1、服务器故障时候会丢失数据。也就是服务器突然嗝屁,Redis没来得及保存数据。但如果保存时间太频繁,又影响性能。

AOF 的优点
1、AOF 的默认策略为每秒钟 fsync 一次,在这种配置下,Redis 仍然可以保持良好的性能,并且就算发生故障停机,也最多只会丢失一秒钟的数据。

AOF 的缺点
1、对于相同的数据集来说,AOF 文件的体积通常要大于 RDB 文件的体积。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Linux上使用Redis,首先需要确保Redis服务已经启动。可以使用命令"ps -ef|grep redis"来查看Redis服务是否已经启动。如果没有启动,需要进入Redis的解压缩目录,使用命令"redis-server redis.conf"来启动Redis服务。启动成功后,可以使用"redis-cli"命令来进入Redis命令行界面,然后就可以执行Redis命令了。如果想让Redis服务在后台启动,可以修改Redis配置文件redis.conf,将"daemonize"设置为"yes",然后重新启动Redis服务。关闭Redis服务可以使用"redis-cli shutdown"命令或者使用"kill -9 pid"命令来终止Redis进程。 #### 引用[.reference_title] - *1* [Linux下redis安装和使用(详细版)](https://blog.csdn.net/qq_45056878/article/details/115050645)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [linux redis简单操作](https://blog.csdn.net/weixin_44167504/article/details/123418112)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [redis linux 上详细流程总结](https://blog.csdn.net/weixin_58775072/article/details/127667836)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值