2023-07-28
原文作者:说好不能打脸 原文地址:https://yinwj.blog.csdn.net/article/details/53407288

1、综述

Redis是一款内存数据库,所谓内存数据库是指它存储数据的主要介质是内存而非传统意义的磁盘,后者只用于辅助功能。Redis可以当作NoSQL数据库,缓存和消息代理来使用,目前各行业实践中使用Redis最多的场景还是把它当成缓存子系统,例如存储在线用户的登录情况,存储1小时内提交的订单情况等,缓存图片路径或者图片内容等等;其次较多的场景是作为消息代理来使用,例如DUBBO支持使用Redis进行事件订阅和通知。

Redis的发起者是Salvatore Sanfilippo,最初开发它的目的就是为了解决快速存储和查询社交网站上常见的好友关系数据。目前Vmware在资助着Redis项目的开发和维护,Redis最新的版本是3.X(本文写作时为version 3.2.5),其中内置支持了很多实用的数据存储结构,例如string, hashes, lists, set, sorted sets等,还提供了很多实用的高性能、高可靠特性,例如集合运算、LRU缓存内容管理、主从同步等等。

在本专题讨论Redis时,会首先花一些较少的篇幅介绍Redis的基本安装和使用,然后将深入Redis所支持的数据结构主要讲解Redis底层设计对这些数据结构的支撑,接下来会介绍Redis的主要配置优化事项,最后介绍Redis的集群搭建方式(基于3.X版本)和实施案例。

2、快速安装和基本配置说明

2-1、快速安装

Redis官方网站非常好记:https://redis.io/,安装也非常简单。请到官网下载最新发布的稳定版本:http://download.redis.io/releases/redis-3.2.5.tar.gz,解压后可直接make & make install。注意,类似Centos 6.X的老版本操作系统,在安装时可能会报一些错误,依次解决就行了:

  • make: cc: Command not found make:
    # make install
    > make: cc: Command not found make***

遇到这个错误,说明没有安装编译工具。yum安装 gcc 即可:

    # yum install -y gcc
  • You need tcl 8.5 or newer in order
    # make test
    > error:You need tcl 8.5 or newer in order

这是因为相应软件的版本太老了,下载一个安装就行:

    # wget http://downloads.sourceforge.net/tcl/tcl8.6.1-src.tar.gz
    ......
    解压
    ......
    # cd ./unix/
    ......
    安装即可
    ......
  • 安装过程中还可能有其它问题,按照报错解决就可以了

这些问题解决后,就可以安装Redis 3.2的版本了:

    # make install
    ......
    Hint: It's a good idea to run 'make test' ;)
    ......
    INSTALL install
    INSTALL install
    INSTALL install
    INSTALL install
    INSTALL install
    ......

2-2、客户端连接测试

Redis的客户端组件可以和Spring框架无缝集成,还兼容多种开发语言:如PHP、Go、C#、python、C++、NodeJS等等。下面我们单纯使用Redis的Java客户端组件Jedis,完成一个简单的Redis服务端连接,并向服务器写入一个Key-Value值。我们使用的Jedis版本为2.8,您首先需要在Maven工程中引入这个组件:

    ......
    <dependency> 
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
        <version>2.8.0</version>
    </dependency>
    ......

以下是Java测试程序的主要代码片段:

    ......
    Jedis redisClient = new Jedis("192.168.61.140", 6379);
    // 写入一个K-V值
    redisClient.set("key1", "value");
    redisClient.close();
    ......

通过以上代码,我们向Redis服务器写入了一个K-V键值对,那么这个操作是否成功了呢?我们可以使用Redis自带的Client功能进行查看:

    # redis-cli -h 192.168.61.140
    192.168.61.140:6379> get key1
    "value"

Redis自带的Client功能非常强大,包括写入、查询、监控、调试等,从以上的“get”命令结果来看Java客户端代码上的写入操作是成功了。但那只是最简单的写入操作,Redis支持的多种复杂数据结构以及他们的组织方式,我们将在后文进行详细讨论。

3、基本配置参数

Redis 3.2版本中,最重要的配置文件就是存在于安装目录中的名叫redis.conf的文件。其中的范本格式清楚说明了Redis 3.2版本中可以配置的主要信息和含义。主要包括几个方面:网络配置项、一般配置项、快照配置项、复制(高可用)配置项、集群配置项、安全配置项、资源限制配置项、LUA脚本配置、慢日志配置、监控配置、事件通知配置、数据结构高级配置等。

本节内容将首先讨论一些基础配置项,后续文章中在介绍Redis对各种数据结构支持时再介绍数据结构相应的配置项,介绍Redis数据快照原理时再介绍快照配置项,介绍Redis高可用方案和集群方案时再介绍相应的配置选项。

3-1、网络配置项和一般配置项

  • bind:绑定的主机地址,不设置默认将处理所有请求。由于一台主机可能有多个IP,如果这里设置192.168.1.100,那么Redis只会处理达到这个IP的数据请求。
  • protected-mode:设置是否开启网络保护模式,默认为yes(开启)。这个选项的工作方式是,如果您没有设置了bind参数,也没有设置安全登录密码,则当这个参数开启时Redis只允许本地连接的客户端访问。也就是说如果您不设置bind参数,而又需要其它客户端通过网络访问,那么就设置这个参数为no(关闭)吧。
  • port:Redis服务的工作端口,默认为6379。
  • tcp-backlog:在Linux服务器上有一个配置参数“net.core.somaxconn”,这是参数表示socket监听(listen)的backlog上限。所谓backlog是指已经和服务器完成了TCP三次握手确认,但是还没有被上层应用程序处理的请求队列。这个参数在操作系统层面的默认值是128,很显然在压力非常大的系统上,这个值小了一点。您可以修改成2048或者更大,而为Redis配置的tcp-backlog应该小于或者等于您在操作系统上设置的最大限制值(否则Redis上面设置再大也没有用)。net.core.somaxconn参数的调整可参见其它资料。
  • timeout:该参数表示当某一个客户端连接上来并闲置timeout(单位秒)的时间后,Redis服务端就主动关闭这个客户端连接。该配置参数的默认值为0,表示关闭这个功能。
  • tcp-keepalive:客户端TCP连接的健康性检查,如果不设置为0就表示Redis服务端会定时发送SO_KEEPALIVE心跳机制检测客户端的反馈情况。该配置的默认值为300秒,既是300秒检测一次。健康性检查的好处是,在客户端异常关闭的情况下,Redis服务端可以发现这个问题,并主动关闭对端通道。这个参数建议开启。
  • daemonize:当为yes的时候,以守护进程的模式运行。该参数的默认值为 no,主要目的是为了在测试环境下调试方便;当运行在生产环境时,可以将这个选项配置为yes。
  • pidfile:当Redis没有以守护进程的方式运行,这个pid文件的配置选项不会起作用。当redis以守护进程方式运行时,这个配置选项设置的文件就会被创建和使用。
  • loglevel:配置的Redis日志级别,默认为notice。这个选项可以设置以下这些值: debug ,非常多的信息无论有用的还是没用的都会被显示或者记录,一般用于开发和测试状态; verbose ,比起debug要少很多,但是也极少出现有用的信息; notice ,信息量适度而且一般不会错过有用的信息,可用于生产环境; warning ,只有非常有用和危险的信息会被显示或者记录,建议使用warning级别的日志记录模式。
  • logfile:日志文件存在的位置,默认为空字符串设置,这时日志会打印到标准输出设备。
  • syslog-enabled:默认为no(开启),当配置为yes时,Redis的日志会输出到系统日志。
  • databases:从Redis很早的版本开始,它就支持多个独立的内存数据库同时存在。该值设置数据库的数量,默认数据库为16,可以使用SELECT 命令在连接上指定数据库id。

3-2、安全和资源限制配置项

  • requirepass:该选项指定客户端在完成连接后,在执行任何其它命令前必须使用的鉴权密码。这在技术团队需要拒绝一些不信任的客户端访问Redis服务的情况下,是比较有用的。
  • rename-command:在生产环境下,有一些Redis命令是非常危险的,例如FLUSHALL命令和FLUSHDB命令。所以Redis服务器为生产环境的指令安全性提供了一个重命名功能,通过这个功能我们可以将一些需要避免执行的指令变更成其它指令。例如以下设定可以将FLUSHALL指令变更成空字符:
        ......
        rename-command FLUSHALL ""
        rename-command FLUSHDB ""
        ......
这是再使用Redis的客户端执行以上命令,就会收到以下的提示:
        ......
        // 开启了密码功能,并设置密码为123456
        
        # redis-cli -h 192.168.61.140 -a 123456
        
        192.168.61.140:6379> FLUSHDB
        (error) ERR unknown command 'FLUSHDB'
        192.168.61.140:6379> FLUSHALL
        (error) ERR unknown command 'FLUSHALL'
        ......
  • maxclients:设定当前同时连接到本Redis服务上的客户端数量,默认为10000。注意这个值的设定还和操作系统上file limit参数有关联,实际情况是10000个同时正常的客户端连接完全够用,如果实际情况需要调整则一定要同时确认该设定值没有超过操作系统上设定的文件描述符限制数量。
  • maxmemory:该选项是告诉Redis当使用了多少物理内存后就开始拒绝后续的写入请求,该参数能很好的保护好你的Redis不会因为使用了过多的物理内存而导致swap,最终严重影响性能甚至崩溃。该参数的设置单位为bytes,建议的设置范围不要超过操作系统可支配内存的 3/5,例如您的操作系统可支配8GB内存,那么建议的设置值就是5GB,也就是5242880k、5120mb、5gb。在配置容量大小时,Redis支持各种单位简写,也就是说1GB 1Gb 1gB都是一个意思。如果不设置该参数就表示不限制,但这种方式在生产环境下不推荐。
  • maxmemory-policy: 这个参数非常重要,它设置了当内存达到最大可用数量时的内存清除策略 。该选项可以设置以下这些值: volatile-lru 设定值,使用Redis时如果不是有特殊的存储要求,都建议设定Key的过期时间expire。一旦设置了过期时间Redis会将这些Key放置到一个LRU队列中(关于LRU队列算法的内容可以参考本专题之前的文章),Redis使用“惰性删除”+“定期删除”的方式对LRU队列中过期的Key进行清理。当内存达到满载状态时,Redis也会启动一次清除操作。 allkeys-lru 设定值将忽略Key的过期时间设定,将所有Key放入LRU队列并清除过期的数据。 volatile-random 该选项将对过期的Key值采取“随即选取”算法进行清除。allkeys-random选项和volatile-random选项类似,只不过将Key的选取范围扩大到了所有Key,而不只针对设定了过期时间expire的Key。 volatile-ttl ,该选项将清除当前即将过期的Key(最小TTL算法)。 noeviction ,如果清除策略设置该值,在Redis内存满载情况下将不启动任何清除策略,直接拒绝后续的写操作。 noeviction是一个默认策略 ,所以建议在生产环境中一定要进行清除策略的修改。
  • maxmemory-samples:以上提到的LRU算法和TTL算法在Redis中的实现并不是固定的,Redis支持技术人员根据实际情况在算法性能和精度间进行调整。maxmemory-samples配置项实际上就是一个Key的抽样值,值越高算法精度越高。例如设置为10的时候,Redis中的LRU算法基本上处理失效的Key就非常精确了,但是却需要消耗较多的CPU资源;设置为3的时候,虽然处理失效的Key精度不高,但是处理速度非常快。该选项的默认值为5。

3-3、日志和监控配置项

3-3-1、慢日志

Redis从很早的版本就提供了一个慢操作的日志记录功能,称为慢日志。当Redis中某一个内部操作所耗费的时间超过了设定的一个限制阀值,这个操作就会被慢日志功能记录在内存中。注意这里提到的是内部操作时间,并不包括可能的网络I/O操作时间。

通过Redis的客户端使用slowlog get、slowlog len、slowlog reset等命令可以查看当然Redis服务端记录的慢日志情况。Redis的配置信息中提供了两个参数供技术团队调整慢日志功能:slowlog-log-slower-than和slowlog-max-len。

  • slowlog-log-slower-than:这个参数就是给定慢日志的时间阀值,单位为微妙。也就是说1000000等于1秒。该参数的默认为10000。请注意,如果该参数的值设置为负数,将禁用慢日志功能;如果设置为0,将会记录每一条操作日志。
  • slowlog-max-len:这个参数存储Redis服务端能够记录的慢日志总长度。这个数值没有上限,只是需要技术团队注意这会消耗宝贵的内存资源,实际上默认的128就是比较实用的设置值。

3-3-2、延迟监控功能

LATENCY监控器功能,是从Redis Version 2.8.3开始提供的一个重要的反映其延迟状态的监控功能。其工作任务是当技术人员设置了一个延迟操作的时间阀值后,凡是超过了这个阀值时间的操作都将被认为是执行缓慢的操作被记录下来。Redis客户端在登录后,可以使用诸如LATENCY LATEST、LATENCY HISTORY、LATENCY RESET、LATENCY GRAPH、LATENCY DOCTOR等命令控制/查询LATENCY监控器。LATENCY监控器功能更详细的介绍,可以参看Redis官方文档中的介绍:https://redis.io/topics/latency-monitor

latency-monitor-threshold,这个参数项用来设置操作时间的阀值,如果关闭延迟监控功能的话,可以将这个值设置为0。另外客户端连接可以独立设置这个阀值,只需要在连接Redis服务端成功后,执行“CONFIG SET latency-monitor-threshold XXXX”命令即可。

4、后文介绍

后面的文章我们将讨论Redis的如下基本知识:

a、事件功能和配置项
b、基础数据结构
string
list
hash
set
zset
c、深入数据结构和内存优化
d、Redis集群案例
集群方案(1)
集群方案(2)

阅读全文