不苟言笑

面试官:小伙子,谈谈对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-sclyum -y install devtoolset-9-gcc devtoolset-9-gcc-c++ devtoolset-9-binutils

1.3.2、加环境变量并失效

scl enable devtoolset-9 bashecho "/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正式启动胜利,上面会带来根本用法介绍。

pingpong

1.5、设置明码

默认是没有凋谢明码设置的,须要手动开启正文掉的参数配置。

#编辑配置文件vim /opt/redis-6.0.8/redis.conf#本来的被正文掉,复制一行改成你设置的明码即可#requirepass foobaredrequirepass 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解压的或者装置的目录以管理员身份运行cmdredis-server --service-start

2.4、cmd下运行测试登录

#在redis解压的或者装置的目录以管理员身份运行cmdredis-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 100auto-aof-rewrite-min-size 64mb

在启动时Redis会逐行执行AOF文件中的命令将硬盘中的数据加载到内存中,加载的速度相比RDB会慢一些。

尽管每次执行更改数据库内容的操作时,AOF都将命令记录在AOF文件中。但事实上,因为操作系统的缓存机制,数据并没与真正写入硬盘,而是进入了操作系统的硬盘缓存。在默认状况下,操作系统每30秒会执行一次同步操作,以便将硬盘缓存中的内容写入硬盘。

在Redis中能够通过appendfsync设置同步的机会

# appendfsync always#默认设置为everysecappendfsync 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.outnohup /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在主从数据库之间复制数据的过程自身是异步的,这就意味着,主数据库执行完客户端申请的命令会立刻将命令在主数据库的执行后果反馈给客户端,并异步的将数据同步给从库,不会期待从数据库接管到该命令在返回给客户端。

当数据至多同步给指定数量的从库时,才是可写,通过参数指定:

#设置起码限度3min-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.confredis-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>