暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Redis基础

Linux Windows server学习交流 2020-04-22
149

Redis是一款,ANSI C语言编写的,高级键值(key-value)缓存和支持永久存储NoSQL数据库产品。

支持多种(5种)数据类型:string,hash,list,set,zset。

功能:

高速读写,数据类型丰富,支持持久化,多种内存分配和回收策略,支持事务,消息队列、消息订阅,支持高可用,支持分布式集群。

企业缓存数据库解决方案

Memcached、Redis、Tair(淘宝缓存)

Memcached:多核的缓存服务,更加适合于多用户并发访问(访问次数少的应用场景)

Redis:单核的缓存服务,在单节点情况下,更加适合少量用户,多次访问的场景

Redis单机安装部署

    ## 先安装编译软件
    [root@docker02 ~]# yum install gcc
    [root@docker02 ~]# mkdir data/redis -p
    [root@docker02 ~]# cd data/redis
    [root@docker02 redis]# wget http://download.redis.io/releases/redis-5.0.2.tar.gz
    [root@docker02 redis]# tar xf redis-5.0.2.tar.gz
    [root@docker02 redis]# ln -s redis-5.0.2 redis
    [root@docker02 redis]# ll
    total 1912
    lrwxrwxrwx 1 root root 11 Apr 17 17:02 redis -> redis-5.0.2
    drwxrwxr-x 6 root root 4096 Nov 22 2018 redis-5.0.2
    -rw-r--r-- 1 root root 1952989 Nov 22 2018 redis-5.0.2.tar.gz
    [root@docker02 redis]# cd redis
    ## 编译
    [root@docker02 redis]# make
    ## 添加环境变量
    ## 此处填写的是本机redis-server的安装路径
    [root@docker02 ~]# cat etc/profile.d/redis.sh
    export PATH="/data/redis/redis/src:$PATH"
    ## 刷新新增的环境变量
    [root@docker02 ~]# source etc/profile.d/redis.sh


    redis的基本配置

      [root@docker02 ~]# mkdir data/redis/6379/logs -p
      [root@docker02 ~]# cd data/redis/6379/
      [root@docker02 6379]# cat redis.conf
      daemonize yes
      pidfile /data/redis/6379/redis-6379.pid
      port 6379
      bind 127.0.0.1
      timeout 300
      loglevel notice
      logfile /data/redis/6379/logs/redis-6379.log
      syslog-enabled no
      databases 16
      requirepass redis.123


        ### redis配置文件详解
        daemonize yes #是否以后台进程运行
        pidfile var/run/redis/redis-server.pid #pid文件位置
        port 6379 #监听端口
        bind 127.0.0.1 #绑定地址,如外网需要连接,设置0.0.0.0,多个使用空格
        timeout 300 #连接超时时间,单位秒
        loglevel notice #日志级别,分别有:
        # debug :适用于开发和测试
        # verbose :更详细信息
        # notice :适用于生产环境
        # warning :只记录警告或错误信息
        logfile var/log/redis/redis-server.log #日志文件位置
        syslog-enabled no #是否将日志输出到系统日志
        databases 16#设置数据库数量,默认数据库为0


        ############### 快照方式 ###############
        save 900 1 #在900s(15m)之后,至少有1个key发生变化,则快照
        save 300 10 #在300s(5m)之后,至少有10个key发生变化,则快照
        save 60 10000 #在60s(1m)之后,至少有1000个key发生变化,则快照
        rdbcompression yes #dump时是否压缩数据
        dir var/lib/redis #数据库(dump.rdb)文件存放目录


        ############### 主从复制 ###############
        slaveof <masterip> <masterport> #主从复制使用,用于本机redis作为slave去连接主redis
        masterauth <master-password> #当master设置密码认证,slave用此选项指定master认证密码
        slave-serve-stale-data yes #当slave与master之间的连接断开或slave正在与master进行数据同步时,如果有slave请求,当设置为yes时,slave仍然响应请求,此时可能有问题,如果设置no时,slave会返回"SYNC with master in progress"错误信息。但INFO和SLAVEOF命令除外。


        ############### 安全 ###############
        requirepass foobared #配置redis连接认证密码


        ############### 限制 ###############
        maxclients 128#设置最大连接数,0为不限制
        maxmemory <bytes>#内存清理策略,如果达到此值,将采取以下动作:
        # volatile-lru :默认策略,只对设置过期时间的key进行LRU算法删除
        # allkeys-lru :删除不经常使用的key
        # volatile-random :随机删除即将过期的key
        # allkeys-random :随机删除一个key
        # volatile-ttl :删除即将过期的key
        # noeviction :不过期,写操作返回报错
        maxmemory-policy volatile-lru#如果达到maxmemory值,采用此策略
        maxmemory-samples 3 #默认随机选择3个key,从中淘汰最不经常用的


        ############### 附加模式 ###############
        appendonly no #AOF持久化,是否记录更新操作日志,默认redis是异步(快照)把数据写入本地磁盘
        appendfilename appendonly.aof #指定更新日志文件名
        # AOF持久化三种同步策略:
        # appendfsync always #每次有数据发生变化时都会写入appendonly.aof
        # appendfsync everysec #默认方式,每秒同步一次到appendonly.aof
        # appendfsync no #不同步,数据不会持久化
        no-appendfsync-on-rewrite no #当AOF日志文件即将增长到指定百分比时,redis通过调用BGREWRITEAOF是否自动重写AOF日志文件。


        ############### 虚拟内存 ###############
        vm-enabled no #是否启用虚拟内存机制,虚拟内存机将数据分页存放,把很少访问的页放到swap上,内存占用多,最好关闭虚拟内存
        vm-swap-file var/lib/redis/redis.swap #虚拟内存文件位置
        vm-max-memory 0 #redis使用的最大内存上限,保护redis不会因过多使用物理内存影响性能
        vm-page-size 32 #每个页面的大小为32字节
        vm-pages 134217728 #设置swap文件中页面数量
        vm-max-threads 4 #访问swap文件的线程数


        ############### 高级配置 ###############
        hash-max-zipmap-entries 512 #哈希表中元素(条目)总个数不超过设定数量时,采用线性紧凑格式存储来节省空间
        hash-max-zipmap-value 64 #哈希表中每个value的长度不超过多少字节时,采用线性紧凑格式存储来节省空间
        list-max-ziplist-entries 512 #list数据类型多少节点以下会采用去指针的紧凑存储格式
        list-max-ziplist-value 64 #list数据类型节点值大小小于多少字节会采用紧凑存储格式
        set-max-intset-entries 512 #set数据类型内部数据如果全部是数值型,且包含多少节点以下会采用紧凑格式存储
        activerehashing yes #是否激活重置哈希



        启动redis-server

          ## 上一步的刷新环境变量后,就可以在任意目录下使用redis的命令
          [root@docker02 ~]# redis-server data/redis/6379/redis.conf
          [root@docker02 ~]# ps -ef|grep 'redis'
          root 5447 1 0 11:07 ? 00:00:00 redis-server 127.0.0.1:6379


          验证redis-server

            [root@docker02 ~]# redis-cli -h 127.0.0.1      ## 登陆,默认6379
            127.0.0.1:6379> auth redis.123 ## 密码验证
            OK
            127.0.0.1:6379> keys * ## 查看keys
            (empty list or set)


            Redis单机多实例安装部署

              ## 同一台主机启动一个端口号为6380的redis-server
              [root@docker02 ~]# mkdir data/redis/6380/logs -p
              [root@docker02 ~]# cat data/redis/6380/redis.conf
              daemonize yes
              pidfile data/redis/6380/redis-6380.pid
              port 6380
              bind 127.0.0.1
              timeout 300
              loglevel notice
              logfile data/redis/6380/logs/redis-6380.log
              syslog-enabled no
              databases 16
              requirepass redis.456
              [root@docker02 ~]# redis-server data/redis/6380/redis.conf
              [root@docker02 logs]# ps -ef|grep 'redis'
              root 5447 1 0 11:07 ? 00:00:00 redis-server 127.0.0.1:6379
              root 7830 1 0 11:15 ? 00:00:00 redis-server 127.0.0.1:6380
              [root@docker02 6380]# redis-server data/redis/6380/redis.conf
              [root@docker02 6380]# redis-cli -h 127.0.0.1 -p 6380
              127.0.0.1:6380> auth redis.456
              OK
              127.0.0.1:6380> keys *
              (empty list or set)




              ## 同一台主机启动一个端口号为6381的redis-server
              [root@docker02 ~]# mkdir data/redis/6381/logs -p
              [root@docker02 ~]# cat data/redis/6381/redis.conf
              daemonize yes
              pidfile data/redis/6381/redis-6381.pid
              port 6381
              bind 127.0.0.1
              timeout 300
              loglevel notice
              logfile data/redis/6381/logs/redis-6381.log
              syslog-enabled no
              databases 16
              requirepass redis.789




              [root@docker02 ~]# redis-server data/redis/6381/redis.conf
              [root@docker02 6380]# ps -ef|grep 'redis'
              root 5447 1 0 11:07 ? 00:00:00 redis-server 127.0.0.1:6379
              root 8507 1 0 11:17 ? 00:00:00 redis-server 127.0.0.1:6380
              root 9096 1 0 11:19 ? 00:00:00 redis-server 127.0.0.1:6381




              [root@docker02 ~]# redis-cli -h 127.0.0.1 -p 6381
              127.0.0.1:6381> auth redis.789
              OK
              127.0.0.1:6381> keys *
              (empty list or set)



              RDB持久化介绍

              什么是持久化:

              持久化:就是将内存中的数据,写入到磁盘上,并且是永久存在的。


              可以在指定的时间间隔内生成数据集的时间点快照(point-in-time snapshot)

              RDB持久化的优点:

              1. RDB是一种表示某个即时点的Redis数据的紧凑文件。RDB文件适用于备份。例如,你可能想要将每小时归档24小时的RDB文件,每天保存近30天的RDB快照。这允许你很容易的恢复不同版本的数据集以容灾。

              2. RDB非常适合于灾难恢复,作为一个紧凑的单一文件,可以被传输到远程的数据中心。

              3. RDB最大化了Redis的性能,因为Redis父进程持久化时唯一需要做的是启动(fork)一个子进程,由子进程完成所有剩余工作。父进程实例不需要执行像磁盘IO这样的操作。

              4. RDB在重启保存了大数据集的实例时比AOF要快。

              RDB持久化的缺点:

              1. 当你需要在Redis停止工作(例如停电)时最小化数据丢失,RDB可能不太好。你可以配置不同的保存点(save point)来保存RDB文件(例如,至少5分钟保存一次或者对数据集第100次写入后,当然也可以设置其他保存时间)。然而,你通常每隔5分钟或更久创建一个RDB快照,所以一旦Redis因为任何原因没有正确关闭而停止工作,你就要做好最近几分钟数据丢失的准备了。

              2. RDB需要经常调用fork()子进程来持久化到磁盘。如果数据集很大的话,fork()比较耗时,结果就是,当数据集非常大并且CPU性能不够强大的话,Redis会停止服务客户端几毫秒甚至一秒。AOF也需要fork(),但是你可以调整多久频率重写日志而不会有损(trade-off)持久性(durability)。


              RDB持久化的优缺点总结:

              优点:速度快,适合于用作备份,主从复制也是基于RDB持久化功能实现的。

              缺点:会有数据丢失,导致服务停止几秒。



              RDB持久化核心配置文件:

                [root@docker02 ~]# cat /data/redis/6379/redis.conf
                ...
                ## 持久化数据文件存储位置
                dir /data/redis/6379/rdb
                ## rdb持久化数据文件名
                dbfilename dump.rdb
                #900秒(15分钟)内有1个更改
                save 900 1#300秒(5分钟)内有10个更改
                save 300 10#60秒(1分钟)内有10000个更改
                save 60 10000
                ...




                AOF持久化介绍

                AOF(append only file)只追加文件,记录服务器执行的所有写操作命令,并在服务器启动时,通过重新执行这些命令来还原数据集。AOF文件中的命令全部以Redis协议的格式来保存,新命令会被追加到文件的末尾。



                AOF持久化优点:

                1. 使用AOF Redis会更具有可持续性(durable):你可以有很多不同的fsync策略:没有fsync,每秒fsync,每次请求时fsync。使用默认的每秒fsync策略,写性能也仍然很不错(fsync是由后台线程完成的,主线程继续努力地执行写请求),即便你也就仅仅只损失一秒钟的写数据。

                2. AOF日志是一个追加文件,所以不需要定位,在断电时也没有损坏问题。即使由于某种原因文件末尾是一个写到一半的命令(磁盘满或者其他原因),redis-check-aof工具也可以很轻易的修复。

                3. 当AOF文件变得很大时,Redis会自动在后台进行重写。重写是绝对安全的,因为Redis继续往旧的文件中追加,使用创建当前数据集所需的最小操作集合来创建一个全新的文件,一旦第二个文件创建完毕,Redis就会切换这两个文件,并开始往新文件追加。

                4. AOF文件里面包含一个接一个的操作,以易于理解和解析的格式存储。你也可以轻易的导出一个AOF文件。例如,即使你不小心错误地使用FLUSHALL命令清空一切,如果此时并没有执行重写,你仍然可以保存你的数据集,你只要停止服务器,删除最后一条命令,然后重启Redis就可以。



                AOF持久化缺点:

                1. 对于同样的数据集,AOF文件通常要大于等价的RDB文件

                2. AOF可能比RDB慢,这取决于准确的fsync策略。通常fsync设置为每秒一次的话性能仍然很高,如果关闭fsync,即使在很高的负载下也和RDB一样的快。不过,即使在很大的写负载情况下,RDB还是能提供能好的最大延迟保证。

                3. 在过去,我们经历了一些针对特殊命令(例如,像BRPOPLPUSH这样的阻塞命令)的罕见bug,导致在数据加载时无法恢复到保存时的样子。这些bug很罕见,我们也在测试套件中进行了测试,自动随机创造复杂的数据集,然后加载它们以检查一切是否正常,但是,这类bug几乎不可能出现在RDB持久化中。为了说得更清楚一点:Redis AOF是通过递增地更新一个已经存在的状态,像MySQL或者MongoDB一样,而RDB快照是一次又一次地从头开始创造一切,概念上更健壮。但是,1)要注意Redis每次重写AOF时都是以当前数据集中的真实数据从头开始,相对于一直追加的AOF文件(或者一次重写读取老的AOF文件而不是读内存中的数据)对bug的免疫力更强。2)我们还没有收到一份用户在真实世界中检测到崩溃的报告。



                AOF持久化优缺点总结

                优点:可以最大程度保证数据不丢失

                缺点:日志记录量级比较大



                AOF持久化核心配置参数

                  [root@db01 redis]# cat /data/redis/6379/redis.conf
                  ...
                  ## 是否打开AOF日志功能
                  appendonly yes/no
                  ## 每一条命令都立即同步到AOF
                  appendfsync always
                  ## 每秒写一次
                  appendfsync everysec
                  ## 写入工作交给操作系统,由操作系统判断缓冲区大小,统一写入到AOF
                  appendfsync no
                  ...



                  RDB 和 AOF,选型

                  1. 一般来说,如果想达到足以媲美 PostgreSQL 的数据安全性, 你应该同时使用两种持久化功能。

                  2. 如果你非常关心你的数据,但仍然可以承受数分钟以内的数据丢失, 那么你可以只使用 RDB 持久化。

                  3. 有很多用户单独使用AOF,但是我们并不鼓励这样,因为时常进行RDB快照非常方便于数据库备份,启动速度也较之快,还避免了AOF引擎的bug。

                  4. 个人感触:在企业中,通常都使用RDB来做持久化,因为一般redis是在做MySQL的缓存,就算缓存数据丢失,真实的数据还是在MySQL中,之所以用缓存是为了速度,性能而考虑,所以还是建议使用RDB持久化,相对来说会好一些,除非专门用redis来做一个key:value的数据库,而且数据很重要,那么可以考虑使用AOF。



                  RDB快照的工作方式

                  1. 默认情况下,Redis保存数据集快照到磁盘,名为dump.rdb的二进制文件。你可以设置让Redis在N秒内至少有M次数据集改动时保存数据集,或者你也可以手动调用SAVE或者BGSAVE命令。

                  2. 在上文中我们已经在配置文件中做过对应的配置:例如,这个配置会让Redis在每个60秒内至少有1000次键改动时自动转储数据集到磁盘:save 60 1000

                  3. 当 Redis 需要保存 dump.rdb 文件时,服务器执行以下操作:

                  Redis 调用 fork() ,同时拥有父进程和子进程。子进程将数据集写入到一个临时的RDB 文件中。当子进程完成对新 RDB 文件的写入时, Redis 用新RDB 文件替换原来的 RDB 文件,并删除旧的 RDB 文件。

                  1. 这种方式使得 Redis 可以从写时复制机制中获益



                  AOF重写功能介绍

                  1. 因为 AOF 的运作方式是不断地将命令追加到文件的末尾,所以随着写入命令的不断增加, AOF 文件的体积也变得越来越大。举个例子,如果你对一个计数器调用了 100 次 INCR ,那么仅仅是为了保存这个计数器的当前值, AOF 文件就需要使用 100 条记录。然而在实际上,只使用一条 SET 命令已经足以保存计数器的当前值了,其余 99 条记录实际上都是多余的。

                  2. 为了处理这种情况, Redis 支持一种有趣的特性:可以在不断服务客户端的情况下,对 AOF 文件进行重建。执行 BGREWRITEAOF 命令, Redis 将生产一个新的 AOF 文件,这个文件包含重建当前数据集所需的最少命令。



                  AOF有多持久

                  1. 你可以配置 Redis 多久才将数据 fsync 到磁盘一次。

                  有三个选项:每次有新命令追加到 AOF 文件时就执行一次 fsync :非常慢,也非常安全。

                  每秒 fsync 一次:足够快(和使用 RDB 持久化差不多,)并且在故障时只会丢失1秒钟的数据。

                  从不 fsync :将数据交给操作系统来处理。更快,也更不安全的选择。

                  推荐(并且也是默认)的措施为每秒 fsync 一次,这种 fsync 策略可以兼顾速度和安全性。

                  总是 fsync 的策略在实际使用中非常慢,即使在 Redis2.0 对相关的程序进行了改进之后仍是如此。频繁调用 fsync 注定了这种策略不可能快得起来。



                  备份Redis数据

                  1. Redis 对于数据备份是非常友好的,因为你可以在服务器运行的时候对 RDB 文件进行复制:RDB 文件一旦被创建,就不会进行任何修改。

                  2. 当服务器要创建一个新的 RDB 文件时,它先将文件的内容保存在一个临时文件里面,当临时文件写入完毕时,程序才使用临时文件替换原来的 RDB 文件。

                  3. 这也就是说,无论何时, 复制 RDB 文件都是绝对安全的。

                  以下是我们的建议:

                  1)创建一个定期任务(cron job), 每小时将一个 RDB 文件备份到一个文件夹, 并且每天将一个 RDB 文件备份到另一个文件夹。

                  2)确保快照的备份都带有相应的日期和时间信息, 每次执行定期任务脚本时, 使用 find 命令来删除过期的快照:比如说, 你可以保留最近 48 小时内的每小时快照, 还可以保留最近一两个月的每日快照。

                  3)至少每天一次, 将 RDB 备份到你的数据中心之外, 或者至少是备份到你运行 Redis 服务器的物理机器之外。


                  RDB持久化高级配置

                    [root@db01 redis]# cat /data/redis/6379/redis.conf
                    ...
                    ## 后台备份进程出错时,主进程停不停止写入? 主进程不停止容易造成数据不一致
                    stop-writes-on-bgsave-error yes
                    ## 导出的rdb文件是否压缩 如果rdb的大小很大的话建议这么做
                    rdbcompression yes
                    ## 导入rbd恢复时数据时,要不要检验rdb的完整性 验证版本是不是一致
                    rdbchecksum yes
                    ...

                    AOF持久化高级配置

                      [root@db01 redis]# cat /data/redis/6379/redis.conf
                      ...
                      ## 正在导出rdb快照的过程中,要不要停止同步aofno-appendfsync-on-rewrite yes/no#aof文件大小比起上次重写时的大小,增长率100%时重写,缺点:业务开始的时候,会重复重写多次
                      auto-aof-rewrite-percentage 100
                      ## aof文件,至少超过64M时,重写
                      auto-aof-rewrite-min-size 64mb
                      ...
                      文章转载自Linux Windows server学习交流,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                      评论