Redis管理

来源:互联网 发布:java实现快速排序算法 编辑:程序博客网 时间:2024/06/06 04:26

Redis配置

           Redis可以使用内置的默认配置文件,但只能用来测试和开发。因此,最好自己配置Redis配置文件,通常叫做redis.conf。也可以直接使用命令行传送Redis配置参数,但一般用来测试。这时,会在内部生成的一个临时内存配置文件,文件参数会被翻译成redis.conf的格式。

           运行时更改配置:

                   使用命令 CONFIG SETCONFIG GET,如果更改的配置没有对redis.conf产生影响,重启的Redis还是会使用原来的配置文件。需要使用CONFIG SET确保修改了redis.conf。

           配置Redis作为缓存:

                   每个key需要一个过期集合。

                           maxmemory 2mb

                           maxmemory-policy allkeys-lru

                   当超过2M的限制后,使用LRU算法除去key。

                   如果需要存储数据,可以在创建一个实例作为存储,根据你的持久性的需求配置和只保存不与缓存数据相关的key。

Redis设置注意事项

           1.  使用Linux

           2.  将Linux内核的overcommit memory设置1。添加vm.overcommit_memory=1/etc/sysctl.conf或者使用命令sysctlvm.overcommit_memory=1

           3.  设置swap内存。如果Linux没有swap,Redis实例消耗了太多内存,Redis会由于内存不足崩溃或者Linux内核的OOM killer会杀死Redis进程

           4.  如果Redis处理写负载较重的应用时,在磁盘上保存RDB文件或者重写AOF日志会使用2倍于通常使用的内存。额外的内存用来成比例的存储一定数量被写操作改变的内存页,因此,同时也会影响一定比例数量的key

           5.  即使关闭持久化,在使用复制时,Redis会执行RDB保存

           6.  Redis持久化不推荐使用EC2 EBS卷,EBS性能较低。使用临时存储保存持久化,如果可能将持久化文件移到EBS

           7.  使用虚拟机部署Redis,虚拟化管理程序调用fork()很慢。根据数据集大小,阻塞Redis几毫秒到几秒。

           8.  在虚拟光驱下运行使用 daemonize no

          不停机升级和重启Redis实例:

                  目前为止,绝大数情况在不停止Redis修改配置的方法使用CONFIG SET命令

                  常用方式:

                           1.  为你当前的Redis实例设置一个从Redis实例。需要不同的服务器或者一台足够内存的服务器

                           2.  如果在一台服务器,确保在不同的端口启动

                           3.  等待复制初始同步完成

                           4.  使用INFO确保主从实例含有同样数量的key,使用redis-cli检测从服务器是否如你所愿的工作和回复命令

                           5.  配置客户端使用从实例

                           6.  当你确定主实例不在接受任何查询(使用MONITOR命令检查),用SLAVEOF NO ONE命令执行升级从实例为主实例,然后关闭主实例。

主从复制

           Redis主从复制的特性:        

                      1.  一个主服务器可以有多个从服务器

                      2.  从服务器可以接受来自其他从服务器的连接。

                      3.   Redis复制在主服务器端是无阻塞的。在从服务器执行第一次同步的时候,主服务器可以继续执行查询操作。

                      4.   在从服务器端也是无阻塞的。当从服务器第一次执行同步的时候,如果你在redis.conf配置了,可以使用旧的数据作为查询结果。也可以配置从服务器在与主服务器的连接down掉的时候,向客户端发送错误。但是也会有阻塞的时候,当旧数据必须被删除,新的数据加载进来的时候,从服务器会阻塞进入的连接。

                      5.  可以让从服务器执行保存数据的操作。

          复制工作方式

                  建立从服务器后,使用连接发送SYNC命令,第一次连接或者重连接都可以。主服务器在后台执行保存,收集会更改数据的命令,当后台保存完毕,主服务器将保存在磁盘中的数据文件传输到从服务器,从服务器将它们载入内存。主服务器把收集到的命令发送给从服务器。

                  当连接断掉后,从服务器可以自动重新连接到主服务器。但是,当主服务器和从服务器重连接down掉后,就会会开始一个新的同步。

         配置(slave配置文件):

                 slaveof master ip port

                 从服务器默认设置为只读模式,这样就不会被暴露在因特网中,或者网络中不信任的客户端。因为在重新同步或者从服务器重启时,写操作会被丢弃,但经常有部分不重要的临时数据保存在从服务器上,客户端可能会读取,造成数据不协调。

        验证主服务器:

                config set masterauth <password>或者在配置文件中使用masterauth <password>

Redis持久性

         Redis持久性一般为以下几种:

               1.  RDB持久性对你的数据在指定的时间执行实时快照

               2.  AOF持久性由服务器记录每一次写操作,在重启服务器的时候,重构源数据。以Redis协议的格式记录命令。当日志变得太大的时候,Redis会在后台重写日志文件。

               3.  可以同时使用RDB和AOF,但恢复数据的时候使用AOF文件,因为记录了完整的操作。

        RDB优点:

                1.  压缩的单一文件,可以实时的反映Redis数据。RDB文件可以作为备份。

                2.  可以很方便的迁移。

                3.  RDB最大的提升Redis性能,因为Redis parent进程只需要fork一个子进程,然后子进程处理剩下操作。   

                4.  RDB恢复大数据比AOF快。

        RDB缺点:

                1.  当Redis意外停止工作时,数据丢失会较大。

                2.  RDB需要经常调用fork(),让子进程持续进行磁盘操作。fork()可能会耗费大量时间,如果数据比较大,还可能会导致Redis停止服务几毫秒,甚至一秒。如果数据非常大和CPU性能不是很好,会花费大量时间。

        AOF优点:

               1.  有不同的fsync选择:不执行fsync,每秒一次fsync,每次查询时fsync。默认使用每秒一次fsync,只会损失一秒的写操作。fsync被后台线程执行,主线程尽力执行写操作直到没有fsync操作。

               2.  AOF日志只能被添加,不能搜索,如果断电也不会被污染。

               3.  当文件太大的时候,会在后台自动重写AOF。即使Redis继续向旧文件添加数据,重写也是完全安全的,也会以最少的操作对当前的数据集创建一个新的AOF文件,当新文件创建好了,Redis切换两个文件,以后向新的文件添加log。

               4.  AOF文件简单容易理解。

        AOF缺点:

              1.  同样的数据集AOF文件比RDB文件大

              2.  使用精确的fsync策略AOF文件执行比RDB慢。RDB可以保证在很大的延迟甚至是巨大的写负载都能很效的执行。

              3.  目前有一个罕见的bug,重载数据时不是十分准确。RDB没有这个bug。原因是AOF文件增量的更新现有状态,RDB快照每次都从头开始。

        RDB 支持连续快照

               Redis将数据快照保存在磁盘上,是一个叫dump.rdb的二进制文件。可以配置Redis每隔N秒至少数据集有M个改变时保存数据。

               save 60 1000

        Redis RDB转储数据到磁盘上执行的操作:

              1.  Redis调用fork,然后有一个子进程和一个父进程。

              2.  子进程将数据写到一个临时RDB文件

              3.  当子进程写完一个新的RDB文件时,替换原来的文件。

        Append-only文件

        在配置文件中打开AOF

                appendonly yes

                每次Redis收到的改变数据集的命令,都会添加到AOF文件。

                当你重启Redis文件时,AOF会被执行恢复Redis原来的状态

        日志重写

                自动在后台重写AOF日志并不中断对客户端的服务。

        AOF持久策略

               同步数据到磁盘上的选项:

               1.  每次一个命令加入到AOF时执行fsync。很慢,但安全

               2.  每秒一次fsync。足够快,但会损失一秒的数据

               3.  从不fsync,将数据保存在操作系统中。最快,最不安全。

        AOF文件崩溃处理办法

               1.  对你的AOF文件做备份

               2.  使用redis-check-aof工具修复原始文件:redis-check-aof --fix

               3.  选择性的使用diff -u检查两个文件的不同

               4.  重启server并使用修复的文件

        AOF工作方式:

               1.  Redis调用fork

               2.  子进程在一个临时文件写新的AOF

               3.  父进程在内存缓冲区中聚集所有新的改变。(同时也会将新的改变写到旧的append-only文件)

               4.  当子进程写完文件后,父进程得到一个信号,添加内存缓冲区中的数据到子进程产生的文件。

               5.  Redis自动重命名旧的文件到新的,开始添加新数据到新的文件。

       从dump.rdb快照切换到AOF

               1.  对你最近的dump.rdb文件做备份

               2.  将备份迁移到安全的地方

               3.  执行:redis-cli config set appendonly yes    redis-cli config set save ""

               4.  确认你的数据库包含同样数量的key

               5.  确保写操作被正确的添加到append only文件

        第一个CONFIG命令打开Append Only File。Redis将会阻塞初始dump,然后为写打开文件,然后添加接下来所有的写查询。

        第二个CONFIG命令关闭持久快照。

        注意:需要编辑redis.conf文件打开AOF,否则重启server后改变的配置操作会丢失,然后以原来的配置启动

        AOF和RDB持久化之间的联系

                当一个RDB快照操作在执行时,不会触发AOF重写,当AOF重写正在执行时,允许执行BGSAVE命令。可以防止两个后台进程同时做大量的磁盘I/O。

                在处理快照时,用户明确的请求一个日志重写操作通过使用 BGREWRITEAOF ,服务器返回OK状态码告诉用户操作已经被安排,当快照完成后重写被立刻执行。

        备份Redis数据

                在数据库运行的时候你也可以copy RDB文件,因为RDB文件只要产生了就不会改变,产生的时候使用临时名字,当新的快照完成后,自动调用rename(2)重命名为最终的名字。

                1.  在你的服务器创建一个定时任务,在一个目录中创建每小时的快照RDB文件,在另一个不同的目录创建每日快照

                2.  每次运行计划任务脚本时,确保调用find命令删除太久的快照,比如保有最近48小时的每小时快照,和一两个月的每日快照。确保正确命名数据快照和时间信息。

                3.  至少每天一次将RDB快照迁移出你的数据中心或者迁移出正在运行Redis实例的机器

        灾难恢复

                 将你的容灾系统挂载在Amazon S3或者其他相似的服务上。将你的日常或者小时快照以加密的形式迁移到S3。

                 将你的快照使用scp迁移到远端服务器。

Redis安全

        Redis安全模型

                   Redis设计在信任的环境被信任的客户端访问。不能直接暴露在网络中,或者应用环境中被不安全的客户端用TCP端口或者UNIX套接字访问。

        Redis常被用来作为数据库,缓存,或者消息队列系统。客户端应用在web端查询Redis生成页面,或者请求执行操作或者web应用程序用户触发执行。

        Web应用是不信任客户端和Redis的中间层

       一般安全的做法,访问Redis应该经由一层实现ACLs,验证用户输入,然后再决定哪些操作送往Redis实例。但是,Redis相比于其性能和简单性,安全性还不够。

        网络安全

                Redis端口应该只允许信任的客户端访问。运行Redis的服务器只能被使用Redis实现的计算机应用程序直接访问

               端口使用防火墙可以阻止外界的访问,但客户端仍可以使用loopback接口访问。

       身份验证功能

               Redis不实现访问控制,但提供一层身份验证,可以在redis.conf文件编辑打开。

              使用了身份验证功能,Redis拒绝不能被验证的客户端的任何查询。客户端发送AUTH命令和密码去验证身份

              密码设置在redis.conf,密码设置足够长防止蛮力攻击。

              身份验证功能在防火墙或者其它保护措施失效后,能起一定保护作用

              AUTH命令和其他Redis命令一样,没有被加密,不能阻止有足够能力进入网络进行窃取的攻击者

              Redis本身不支持加密,可以加一个SSL代理

        禁止指定的命令

                禁止命令或者重命名为不能猜测的名字,限制客户端执行一些指定的命令
                rename-command CONFIG ""(禁止命令)

       从外部精心挑选的输入引发的攻击

               一类攻击可以不通过访问进入实例引发。可以插入数据触发Redis内部的实现数据结构的算法时间复杂度变糟糕,比如通过表单提交,一些字符串应该被散列相同的桶里变结果到了hash表,O(1)变为O(N)。为了预防,Redis使用了每次执行伪随机种子的hash函数。

               Redis实现SORT命令使用了qsort算法,目前,算法不是随机的,可以通过仔细选择正确的输入触发最糟糕的二次项行为

       字符串转义和NoSQL注入

               Redis协议没有转义字符串的概念,不会发生注入。协议使用前缀长度的字符串,完全二进制安全。

       代码安全

               客户端可以完全使用命令集,但访问实例不能控制当前运行的Redis系统。

               在内部,Redis使用了众所周知的编程实践编写安全的代码,阻止缓冲区溢出,格式bug,和其他的一些内存泄露。客户端使用CONFIG命令改变服务器的配置,比如改变工作目录和转储文件。还允许客户端把RDB Redis文件写在随机路径中。这会容易产生安全问题允许运行不安全的代码。

               Redis不需要root权限运行。

Redis基准测试

        Redis含有redis-benchmark功能模仿N个客户端同时发送总共M个查询执行SETs/GETs操作。

    redis-benchmark [-h <host>] [-p <port>] [-c <clients>] [-n <requests]> [-k <boolean>]    -h <hostname>      主机名 (默认 127.0.0.1)    -p <port>          主机端口 (默认 6379)    -s <socket>        主机套接字 (覆盖主机和端口)    -c <clients>       并发连接的数量 (默认 50)    -n <requests>      请求总数 (默认 10000)    -d <size>          SET/GET数据的字节大小(默认 2)    -k <boolean>       1=keep alive 0=reconnect (默认 1)    -r <keyspacelen>   SET/GET/INCR使用随机产生的key, SADD使用随机值使用这个选项 get/set keys时会用mykey_rand:000000012456代替常量key,                       <keyspacelen>参数决定了随机数产生的最大值,比如,设置参数为10,那么产生的随机数范围是rand:000000000000 -                       rand:000000000009    -P <numreq>        Pipeline请求的数量. 默认 1 (不使用pipeline).    -q                 展示query/sec值    --csv              以CSV格式输出    -l                 本地循环. 一直运行测试    -t <tests>         在运行逗号分割列表的测试. 测试的名字与产生输出的名字一样。    -I                 空闲模式. 打开 N 个空闲连接,然后等待.
        如果将Redis和其他的比较,重要的是比较功能和技术上的差异,下面是需要考虑的要点:

  •             Redis是一个服务器,会执行所有网络上的命令和IPC循环。
  •             Redis命令承认所有通常使用的命令。
  •             同步的迭代Redis命令并不是在基准测试Redis,应该测试网络或者IPC延迟。
  •             Redis在内存中存储数据并带有一些持久化保存数据的选项。
  •             Redis是单线程服务器,不能从多核中获益。

        影响Redis性能的因素

               1.  网络带宽和延迟。在执行基准测试前使用ping快速检测客户端和服务器端的延迟是一个良好的做法。对于带宽,比较好的做法是估计Gbits/s 的吞吐量和网络的理论带宽值比较。在很多实际的情况,Redis的吞吐量在网络之前会受限于CPU。

               2.  CPU也会是一个重要因素。由于单线程的,Redis受益于快速的含有巨大缓存的CPU。

               3.  内存的速度和容量对于小的对象影响不大。但对于大于10KB的对象,可能对需要注意。通常购买昂贵的快速内存模块并不是真正的很有效。

               4.  Redis在虚拟机上运行慢。虚拟化对很多普通操作来说代价太高了,Redis并没有增加多少开销在所需的系统调用和网络中断上。

               5.  客户端和服务器在一台机器运行,对于基准测试TCP/IP回送和UNIX域套接字都可以使用。取决于平台,但UNIX域套接字比TCP/IP回送增加50%的吞吐量。

               6.  当大量使用 pipelining时,UNIX域套接字获得的性能好处会减少。

               7.  当以太网访问Redis时,在数据大小小于以太网数据包的大小(大约1500字节)时,聚集命令使用 pipelining会非常有效。

               8.  在多CPU套接字服务器,Redis的表现变得依赖于NUMA配置和处理位置。

               9.  在高端配置,客户端连接的数量也是一个重要的因素。基于epool/kqueue模型,Redis的事件循环是相当可伸缩的。

              10. 在高端的配置,通过调优NIC(s)配置和相关中断可能取得高吞吐量。

              11. 根据平台,Redis编译可以使用不同的内存分配器,这可能有不同的行为在原始速度,内部和外部的碎片方面