共计 6867 个字符,预计需要花费 18 分钟才能阅读完成。
不苟言笑
面试官 :小伙子,谈谈对 Redis 的认识。
我:啊,认识呀,坐着看还是躺着看。Redis 很小?很快?但很长久?
面试官 :不苟言笑的说,我狐疑你在开车,不仅开开车还搞色彩。
我:。。。
面试官 :去去去,我工夫无限,别瞎扯淡。回到正题,你对 Redis 理解有多少。
我:轻量体积小、基于内存十分快、RDB 配合 AOF 长久化让其一样坚挺长久。
面试官 :说点具体的。
我:请看注释。
注释
简介
Redis 是一个开源的、高性能的、基于键值对的缓存与存储系统,通过提供多种键值数据类型来适应不同场景下的缓存与存储需要。与此同时,Redis 的诸多高层级性能让其能够胜任音讯队列、工作队列等不同的角色。除此之外,Redis 还反对内部模块扩大,在某些特定的场景下能够作为主数据库应用。
因为内存的读写速度远快于硬盘,就算当初的固态盘思维预计也是朝着内存那个思维模式倒退的,大略兴许我是个在行,然而短暂存储还是应用机械盘。所以 Redis 数据库中的所有数据都存储在内存中那是相当快的。也有肯定的危险,会导致失落数据,但配合 RDB 以及 AOF 长久化会缩小危险。
一、初识 Redis
1、linux 下装置(Redhat7 系列)
1.1、装置
此处筹备的是源码包,版本不在于最新,在于稳固实用。
其余版本在官网获取,或者在其托管的平台 github 上获取,如下为 Redis 的官网下载地址。
https://redis.io/download
redis-6.0.8.tar.gz
#装置
tar -zxvf redis-6.0.8.tar.gz
#编译
make && make install
1.2、排查谬误
make[1]: *** [server.o] 谬误 1
1.3、解决方案
1.3.1、装置依赖环境
yum -y install centos-release-scl
yum -y install devtoolset-9-gcc devtoolset-9-gcc-c++ devtoolset-9-binutils
1.3.2、加环境变量并失效
scl enable devtoolset-9 bash
echo "/opt/rh/devtoolset-9/enable" >> /etc/profile
从新读取环境变量配置文件
source /etc/profile
从新编译解决问题
# 切换到 Redis 的装置目录, 个别源码包装置会放在 /usr/local/ 上面,看集体应用习惯
cd /opt/redis-6.0.8/
#编译
make && make install
罕用根本命令练习能够参考菜鸟教程
https://www.runoob.com/redis/redis-commands.html
1.4、启动与登录
启动 redis-server 服务端
# 启动 redis 服务
nohup /opt/redis-6.0.8/src/redis-server &
登录 redis-cli 客户端
# 登录 redis-cli
/opt/redis-6.0.8/src/redis-cli
测试验证,此时 linux 下的 redis 正式启动胜利,上面会带来根本用法介绍。
ping
pong
1.5、设置明码
默认是没有凋谢明码设置的,须要手动开启正文掉的参数配置。
# 编辑配置文件
vim /opt/redis-6.0.8/redis.conf
#本来的被正文掉, 复制一行改成你设置的明码即可
#requirepass foobared
requirepass 123456
2、Windows 下装置
2.1、装置
Redis-x64-3.2.100.zip
2.1.1、Windows 下解压或者 msi 间接装置即可。
2.1.2、设置服务命令(注册为服务模式,自启)
装置服务
redis-server --service-install redis.windows-service.conf --loglevel verbose
卸载服务
redis-server --service-uninstall
2.2、启动与敞开
redis-server redis.windows.conf
2.2.1、开启服务
redis-server --service-start
2.2.2、进行服务
redis-server --service-stop
2.3、启动 redis 服务
# 同样在 redis 解压的或者装置的目录以管理员身份运行 cmd
redis-server --service-start
2.4、cmd 下运行测试登录
# 在 redis 解压的或者装置的目录以管理员身份运行 cmd
redis-cli.exe -h 127.0.0.1 -p 6379
#或者间接执行
redis-cli
#执行
redis-cli
#登录测试
ping
5、Windows 下的管理工具 rdm,是可视化界面
https://redisdesktop.com/down…
二、基础知识
1、面试常问到
面试官:redis 中的数据类型有哪些,能聊聊吗?
我:string(字符串类型)、hash(哈希类型)、list(列表类型)、set(汇合类型)、zset(有序汇合类型)、stream(流类型)
stream 是 redis5.0 新增的个性反对。
面试官:嚯,小伙子有点货色啊,晓得的还不少嘛,连 stream 流类型都晓得。
我:一脸懵逼 …
三、进阶
1、长久化
面试官:Redis 的一些高级个性理解吗?
我:略有理解。
面试官:能具体谈谈吗?
我:飞速在大脑搜寻者以前看书总结的。缓存、长久化迎面而来。
将 Redis 作为缓存服务器,但缓存被穿透后会对性能照成较大影响,所有缓存同时生效缓存雪崩,从而使服务无奈响应。
咱们心愿 Redis 能将数据从内存中以某种模式同步到磁盘中,使之重启当前依据磁盘中的记录复原数据。这一过程就是长久化。
面试官:晓得 Redis 有哪几种常见的长久化形式吗?
我:Redis 默认开启的 RDB 长久化,AOF 长久化形式须要手动开启。
Redis 反对两种长久化。一种是 RDB 形式,一种是 AOF 形式。前者会依据指定的规定“定时”将内存中的数据存储到硬盘上,而后者在每次执行命令后将命令本书记录下来。对于这两种长久化形式,你能够独自应用其中一种,但大多数状况下是将二者紧密结合起来。
此时的面试官一脸期待,炯炯有神的看向了我,请持续。
2、RDB 形式
持续介绍,RDB 采取的是快照形式,默认设置自定义快照【主动同步】,默认配置如下。
同样能够手动同步
# 不举荐在生产环境中应用
SAVE
# 异步模式
BGSAVE
# 基于自定义快照
FLASHALL
3、AOF 形式
当应用 Redis 存储非长期数据时,个别须要关上 AOF 长久化来升高过程终止导致数据的失落。AOF 能够将 Redis 执行的每一条命令追加到硬盘文件中,着这个过程中显然会让 Redis 的性能打折扣,但大部分状况下这种状况能够承受。这里强调一点,应用读写较快的硬盘能够进步 AOF 的性能。
默认没有开启,须要手动开启 AOF,当你查看 redis.conf 文件时也会发现 appendonly 配置的是 no
appendonly yes
开启 AOF 长久化后,每次执行一条命令会会更改 Redis 中的数据的目录,Redis 会将该命令写入磁盘中的 AOF 文件。AOF 文件的保留地位和 RDB 文件的地位雷同,都是通过 dir 参数设置,默认的文件名是 appendonly.aof,能够通过 appendfilename 参数批改。
appendfilename "appendonly.aof
实际上 Redis 也正是这样做的,每当达到肯定的条件时 Redis 就会主动重写 AOF 文件,这个条件能够通过 redis.conf 配置文件中设置:
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
在启动时 Redis 会逐行执行 AOF 文件中的命令将硬盘中的数据加载到内存中,加载的速度相比 RDB 会慢一些。
尽管每次执行更改数据库内容的操作时,AOF 都将命令记录在 AOF 文件中。但事实上,因为操作系统的缓存机制,数据并没与真正写入硬盘,而是进入了操作系统的硬盘缓存。在默认状况下,操作系统每 30 秒会执行一次同步操作,以便将硬盘缓存中的内容写入硬盘。
在 Redis 中能够通过 appendfsync 设置同步的机会:
# appendfsync always
#默认设置为 everysec
appendfsync everysec
# appendfsync no
Redis 容许同时开启 AOF 和 RDB。这样既保证了数据的平安,又对进行备份等操作比拟敌对。此时重新启动 Redis 后,会应用 AOF 文件来复原数据。因为 AOF 形式的长久化,将会失落数据的概率降至最小化。
4、Redis 复制
通过长久化性能,Redis 保障了即便服务器重启的状况下也不会失落(少部分遗失)数据。然而数据库是存储在单台服务器上的,不免不会产生各种突发状况,比方硬盘故障,服务器忽然宕机等等,也会导致数据遗失。
为了尽可能的防止故障,通常做法是将数据库复制多个正本以部署在不同的服务器上。这样即便有一台呈现故障,其它的服务器仍旧能够提供服务。为此,Redis 提供了复制(replication)性能。即实现一个数据库中的数据更新后,主动将更新的数据同步到其它数据库上。
此时相熟 MySQL 的同学,是不是感觉与 MySQL 的主从复制很像,以开启二进制日志 binlog 实现同步复制。
而 Redis 中应用复制性能更为容易,相比 MySQL 而言。只须要在从库中启动时退出slaveof
从数据库地址。
# 在从库中配置
slaveof master_database_ip_addr
#测试, 加了 nohup 与 & 是放入后盾,并且输入日志到 /root/ 目录下的 nohup.out
nohup /opt/redis-6.0.8/src/redis-server --6380 --slaveof 192.168.245.147 6379 &
4.1、原理
复制初始化。这里次要原理是从库启动,会向主库发送 SYNC 命令。同时主库接管到 SYNC 命令后会开始在后盾保留快照,即 RDB 长久化的过程,并将快照期间接管的命令缓存起来。当快照实现后,Redis 会将快照文件和所有缓存的命令发送给从数据库。从数据库收到后,会载入快照文件并执行收到的缓存命令。
复制同步阶段会贯通整个主从同步过程,直到主从关系终止为止。在复制的过程中快照起到了至关重要的作用,只有执行复制就会进行快照,即便敞开了 RDB 形式的长久化,通过删除所有 save 参数。
4.2、乐观复制
Redis 采纳了乐观复制(optimistic replication)的复制策略。容忍在肯定工夫内主从数据库的内容是不同的,然而两者的数据最终是会同步的。具体来讲,Redis 在主从数据库之间复制数据的过程自身是异步的,这就意味着,主数据库执行完客户端申请的命令会立刻将命令在主数据库的执行后果反馈给客户端,并异步的将数据同步给从库,不会期待从数据库接管到该命令在返回给客户端。
当数据至多同步给指定数量的从库时,才是可写,通过参数指定:
# 设置起码限度 3
min-slaves-to-write 3
#设置容许从数据最长失去连接时间
min-slaves-max-lag 10
4.3、增量复制
基于以下三点实现
- 从库会存储主库的运行 ID(run id)。每个 Redis 运行实例均会领有一个 惟一运行 ID,每当实例重启后,就会主动生成一个新的运行 ID。相似于 MySQL 的从节点配置的惟一 ID 去辨认。
- 在复制同步阶段,主库一条命令被传送到从库时,会同时把该命令寄存到一个积压队列(backlog)中,记录以后积压队列中寄存的命令的 偏移量范畴。
- 从库接管到主库传来的命令时,会 记录该命令的偏移量。
4.4、留神
当主数据库解体时,状况稍微简单。手动通过从数据库数据库复原主库数据时,须要严格遵循以下准则:
- 在从数据库中应用
SLAVEOF NO ONE
命令将从库晋升为主库持续服务。 - 启动之前解体的主库,而后应用
SLAVEOF
命令将其设置为新的主库的从库。
留神 :当开启复制且数据库敞开长久化性能时, 肯定不要应用 supervisor 以及相似的过程管理工具令主库解体后重启 。同样当主库所在的服务器因故障敞开时,也要防止间接重新启动。因为当主库重启后, 没有开启长久化性能,数据库中所有数据都被清空 。此时从库仍然会从主库中接收数据, 从而导致所有从库也被清空,导致数据库的长久化开了个寂寞。
手动保护的确很麻烦,好在 Redis 提供了一种自动化计划:哨兵 去实现这一过程,防止手动保护易出错的问题。
5、哨兵(sentinel)
从 Redis 的复制历中,咱们理解到在一个典型的一主多从的 Redis 零碎中,从库在整个零碎中起到了冗余备份以及读写拆散的作用。当主库遇到异常中断服务后,开发人员手动将从升主时,使零碎持续服务。过程绝对简单,不好实现自动化。此时可借助哨兵工具。
哨兵的作用
- 监控 Redis 零碎运行状况
- 监控主库和从库是否失常运行
- 主库 gg 思密达,主动将从库升为主库,美滋滋
当然也有多个哨兵监控主从数据库模式,哨兵之间也会相互监控,如下图:
首先须要建设起一主多从的模型,而后开启配置哨兵。
# 主库
sentinel monitor master 127.0.0.1 6379 1
#建设配置文件,例如 sentinel.conf
redis-sentinel /opt/path/to/sentinel.conf
对于哨兵就介绍这么多,当初大脑中有印象。至多晓得有那么回事,能够和美女面试官多掰扯掰扯。
6、集群(cluster)
从 Redis3.0 开始退出了集群这一个性。
即便应用哨兵,此时的 Redis 集群的每个数据库仍然存有集群中的所有数据,从而导致集群的总数据存储量受限于可用内存最小的数据库节点,继而呈现木桶效应。正因为 Redis 所有数据都是基于内存存储,问题曾经很突出,尤其是当 Redis 作为长久化存储服务时。
有这样一种场景。就扩容来说,在客户端分片后,如果像减少更多的节点,须要对数据库进行手动迁徙。迁徙的过程中,为了保证数据的一致性,须要将进群临时下线,绝对比较复杂。
此时思考到 Redis 很小,啊不口误,是轻量的特点。能够采纳预分片(presharding)在肯定水平上防止问题的呈现。换句话说,就是在部署的初期,提前思考日后的存储规模,建设足够多的实例。
从下面的理论知识来看,哨兵和集群相似,但哨兵和集群是两个独立的性能。如果要进行程度扩容,集群是不错的抉择。
配置集群,开启配置文件 redis.conf 中的cluster-enabled
cluster-enabled yes
配置集群每个节点配置不同工作目录,或者批改长久化文件
cluster-config-file nodes-6379.conf
集群测试大家能够执行配置,参考其余书籍亦可,实现并不难。只有是知其原理。
四、Redis for Java
示例
package com.jedis;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
public class Test {
@org.junit.Test
public void demo() {Jedis jedis = new Jedis("127.0.0.1", 6379);
jedis.set("name", "sky");
String params = jedis.get("jedis");
System.out.println(params);
jedis.close();}
@org.junit.Test
public void config() {
// 获取连接池的配置对象
JedisPoolConfig config = new JedisPoolConfig();
// 设置最大连接数
config.setMaxTotal(30);
// 设置最大闲暇连接数
config.setMaxIdle(10);
// 获取连接池
JedisPool pool = new JedisPool(config, "127.0.0.1", 6379);
// 取得外围对象
Jedis jedis = null;
try {
// 通过连接池获取连贯
jedis = pool.getResource();
// 设置对象
jedis.set("poolname", "pool");
// 获取对象
String pools = jedis.get("poolname");
System.out.println("values:"+pools);
} catch (Exception e) {e.printStackTrace();
}finally{
// 开释资源
if(jedis != null){jedis.close();
}
if(pool != null){pool.close();
}
}
}
}
最初放一个制作很粗超的思维导图,一时衰亡,竟然写了这么多。
<H5 align=center>by 龙腾万里 sky 原创不易,白嫖有瘾 </H5>