安装和设置 Redis

本文介绍了在 CentOS 6.x 上建立 Redis 冗余和故障转移环境的步骤。这个步骤分为三个部分,本文只涉及 Redis 的安装方法。

(1):安装Redis
(2):实现Redis的冗余备份
(3):构建基于Redis-Sentinel的故障转移环境

环境

・CentOS 6.x 发布版本
・Redis 3.0.7
・Redis-Sentinel 3.0.7

构成的概述

首先,按照以下结构构建 Redis。

起動ファイルポート設定ファイル説明redis63796379.confRedis 本体です

安装 Redis

有两种安装方法,一种是从软件包导入,另一种是从源代码安装。请考虑个人环境限制并选择合适的安装方式。

若从包装中导入的话

截至2015年11月15日,Redis不包含在标准软件包中。如果在只能使用标准软件库的环境中安装,可以跳过下面提到的“从源代码安装”步骤,而是安装第三方存储库。

设置第三方软件包仓库,需要安装 remi 和 EPEL 仓库,安装步骤如下。由于使用了 tcmalloc 进行内存管理,还需要安装 gperftools-libs。

$ sudo yum install --enablerepo=epel gperftools
$ yum info --enablerepo=remi redis | egrep "Version|バージョン"
Version : 3.0.7
$ sudo yum install --enablerepo=remi redis

检查是否安装了自动启动脚本,并执行以确保正常启动。

$ sudo service redis start
redis-server を起動中:                                     [  OK  ]
$ ps -ef | grep redis
redis 10995 1 0 21:57 ? 00:00:00 /usr/bin/redis-server 127.0.0.1:6379

连接到Redis并确认版本

$ redis-cli info | grep redis_version
redis_version:3.0.7

创建 Redis 的工作目录

在封装版中,配置文件被放置在 /etc/ 目录下。
为了实现 Redis 的冗余备份,需要创建多个配置文件,为了避免混乱,我们将创建一个专门用于 Redis 的工作目录,并将其集中管理。
此外,我们还会赋予 redis 用户写入权限。

Redis的配置文件存放位置为/etc/redis。

$ sudo mkdir /etc/redis
$ sudo chmod 755 /etc/redis
$ sudo chown redis:redis /etc/redis

修正自动启动脚本

由于更改了配置文件的位置,因此需要更改REDIS_CONFIG。
因为要启动多个进程,因此需要将pidfile添加端口号。

$ sudo vi /etc/init.d/redis
:
#pidfile="/var/run/redis/redis.pid"
#REDIS_CONFIG="/etc/redis.conf"
REDISPORT=6379
pidfile="/var/run/redis/redis_${REDISPORT}.pid"
REDIS_CONFIG="/etc/redis/${REDISPORT}.conf"

拷贝 Redis 配置文件。

由于将其设置为每个端口的配置文件,因此将复制原始配置文件。

$ sudo cp -p /etc/redis.conf /etc/redis/6379.conf

完成这一步后,请跳过“编辑Redis配置文件”。

如果从源代码安装的话

从Redis官网下载源代码并安装,最新版本至2016年2月3日为3.0.7。

请确保 Redis 的冗余配置使用的是 2.4.16 或者更高版本的 redis。您可以在这里确认合适的版本,并将以下命令的文件名进行更改。
下载列表

$ cd
$ cd Downlods
$ wget http://download.redis.io/releases/redis-3.0.7.tar.gz
$ tar xzf redis-3.0.*.tar.gz
$ cd redis-3.0.*
$ make
$ sudo make install

如果发生错误,请安装开发工具。

make[3]: gcc: コマンドが見つかりませんでした
make[3]: *** [net.o] エラー 127

$ sudo yum groupinstall 'Development Tools'

如果想要更改默认安装路径,则需要手动修改 redis-3.0.*/src 文件夹中的 Makefile。

PREFIX?=インストール先ディレクトリ名

创建 Redis 用户和组

创建Redis实例的用户和组。
由于不需要登录,因此指定为nologin。

$ sudo groupadd redis
$ sudo useradd -s /sbin/nologin -M -g redis redis

创建Redis的工作目录

新建一个用于Redis的工作目录,并授予redis用户写入权限。所需的工作目录如下所示。

/etc/redis:存放配置文件的位置
/var/run/redis:存放数据文件和启动进程ID文件的位置
/var/log/redis:存放日志输出的位置

$ sudo mkdir /etc/redis /var/run/redis /var/log/redis
$ sudo chmod 755 /etc/redis /var/run/redis /var/log/redis
$ sudo chown redis:redis /etc/redis /var/run/redis /var/log/redis

Redis配置文件的复制

在进行源码安装时,Redis的配置文件模板已经准备好,只需将其复制到目标目录中。
而在进行软件包安装时,配置文件已经预先放置好了。请跳过本章节。

$ sudo cp -p ~/Downloads/redis-3.0.*/redis.conf /etc/redis/6379.conf

Redis服务器的启动和停止

将 Redis 启动脚本作为参数,并通过指定配置文件启动redis用户的方式来启动。

$ sudo -u redis sh -c "redis-server /etc/redis/6379.conf --daemonize yes --dir /var/run/redis"

只要 Redis 正確启动,以下信息将在屏幕上显示出来。

6251:M 03 Feb 04:46:23.166 # You requested maxclients of 10000 requiring at least 10032 max file descriptors.
6251:M 03 Feb 04:46:23.166 # Redis can't set maximum open files to 10032 because of OS error: Operation not permitted.
6251:M 03 Feb 04:46:23.166 # Current maximum open files is 4096. maxclients has been reduced to 4064 to compensate for low ulimit. If you need higher maxclients increase 'ulimit -n'.
                _._                                                  
           _.-``__ ''-._                                             
      _.-``    `.  `_.  ''-._           Redis 3.0.7 (00000000/0) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._                                   
 (    '      ,       .-`  | `,    )     Running in standalone mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 6379
 |    `-._   `._    /     _.-'    |     PID: 6251
  `-._    `-._  `-./  _.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |           http://redis.io        
  `-._    `-._`-.__.-'_.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |                                  
  `-._    `-._`-.__.-'_.-'    _.-'                                   
      `-._    `-.__.-'    _.-'                                       
          `-._        _.-'                                           
              `-.__.-'                                               

我会打开另一个终端并尝试连接到 Redis 客户端。

重要提示:
初始状态下,Redis 并未作为服务启动,所以提示符不会返回。
因此,需要打开另一个终端进行操作。

$ redis-cli -p 6379

用 Redis 服务器执行 PING 命令,确认是否返回 PONG。

127.0.0.1:6379> ping
PONG

请在确认连接后关闭 Redis 服务器
请确认在断开连接后,使用 PING 命令没有返回 PONG。

在默认设置下,由于缺少权限,无法通过 “shutdown” 命令简单地关闭数据文件的写入位置。
请务必在使用 “shutdown” 命令之前,通过 “config set” 命令指定目录。
我们将通过后续的配置文件进行守护进程化来解决这个问题。

127.0.0.1:6379> config set dir /var/run/redis
127.0.0.1:6379> shutdown
not connected>
not connected> ping
Could not connect to Redis at 127.0.0.1:6379: Connection refused
not connected> exit

请使用 ps 命令验证一下,确保 redis 进程未被输出。

$ ps -e | grep redis
★ 何も表示されないこと

自动启动脚本的复制

如果您從源代碼進行安裝,則需要設置自動啟動腳本。
為了在伺服器重啟時自動啟動 Redis,您需要複製並註冊提供的自動啟動腳本。

$ sudo cp -p ~/Downloads/redis-3.0.*/utils/redis_init_script /etc/init.d/redis

我将对自动启动脚本进行修改。
我将在头部的第5行添加 chkconfig: 345 70 15 (在下述的最后一行)。
我还要更改进程ID文件的存放位置。
如果设置了密码,则还需要修改 CLIEXEC。

在Redis中,可以通过设置密码来增强连接时的安全性。
如果设置了密码,则启动脚本中也需要进行设置。
如果不这样做,就无法通过脚本停止Redis服务器进程。
作为解决方法,可以在CLIEXEC中使用-a参数来指定密码。

$ sudo vi /etc/init.d/redis
#!/bin/sh
#
# Simple Redis init.d script conceived to work on Linux systems
# as it does use of the /proc filesystem.
# chkconfig: 345 70 15#CLIEXEC=/usr/local/bin/redis-cli  ★ ここはパスワード設定した場合のみ変更します!!
CLIEXEC="/usr/local/bin/redis-cli -a hoge"
#PIDFILE=/var/run/redis_${REDISPORT}.pid
PIDFILE=/var/run/redis/redis_${REDISPORT}.pid

编辑Redis配置文件

无论是使用包管理器还是源代码,接下来都需要进行必要的设置工作。
我们将对 Redis 服务器进行环境配置。

$ sudo vi /etc/redis/6379.conf
daemonize yes
pidfile redis_6379.pid
port 6379
bind 127.0.0.1
loglevel notice
logfile /var/log/redis/6379.log
dbfilename 6379.rdb
dir /var/run/redis
requirepass hoge
maxclients 1024

以下是各项详细内容:
1. daemonize:将Redis以守护进程的方式启动
2. pidfile:指定Redis进程文件的名称(根据端口号命名)
3. port:指定要启动的端口号
4. bind:指定可连接的服务器IP地址
重要提示:
注释或使用’0.0.0.0’进行解除限制
但为了保证安全性,请限制只允许连接的服务器
本文档中只连接同一台服务器,因此指定为127.0.0.1
如果要从多台服务器连接,请用空格分隔列出IP地址
同时需要使用iptables开放连接服务器的IP和端口
5. 指定日志输出级别
在验证中使用debug或info,在服务运行中使用notice
6. 指定日志文件的名称(根据端口号命名)
7. 指定RDB(保证持久性的快照)文件名(根据端口号命名)
Redis的魅力之一是保证数据的持久性
在某个时刻将内存中的数据写入文件
8. 指定Redis运行时的基本目录
9. 指定密码
重要提示:
这里示例为hoge,但请更改为易于理解和安全的密码
10. 指定可连接的最大连接数
重要提示:
如果要从多个HTTP服务器使用,请考虑服务器数量×MaxClient等因素
在某些情况下,默认的最大连接数1024可能不够用
由于TCP连接使用文件描述符,因此需要考虑操作系统文件打开数的限制值
无法简单地扩展配置值
如果1024不够用,则需要在后面的Redis自动启动文件中更改限制。

Redis启动配置

在配置完Redis服务器之后,我们将通过启动脚本来验证能够启动和停止Redis服务器。

$ sudo /etc/init.d/redis start
Starting Redis server...
$ ps -ef | grep redis
root       3328      1  0 05:27 ?        00:00:00 /usr/local/bin/redis-server 127.0.0.1:6379      

我們將連接到 Redis
我們將使用設定文件中指定的 requirepass 參數作為密碼,通過 auth 命令輸入並進行身份驗證,然後通過 PING 命令確認是否返回 PONG。

$ redis-cli -p 6379
127.0.0.1:6379> auth hoge
OK
127.0.0.1:6379> ping
PONG
127.0.0.1:6379> quit

我会确认自动启动脚本能够正常关闭。

$ sudo /etc/init.d/redis stop
Stopping ...
Redis stopped
$ ps -e | grep redis
$ /usr/local/bin/redis-cli -p 6379
Could not connect to Redis at 127.0.0.1:6379: Connection refused

Redis的启动和关闭,以下命令也可以使用。

$ sudo service redis start
$ sudo service redis restart
$ sudo service redis stop

Redis的自动启动(服务)注册

在将其注册为服务之前,请确保启动脚本能够正常启动和关闭。

$ sudo chkconfig redis on
$ chkconfig --list redis
redis  0:off  1:off  2:on  3:on  4:on  5:on  6:off

我将重新启动服务器并确认Redis会自动启动

$ reboot

服务器重新启动后

$ ps -ef | grep redis
redis      2042      1  0 06:26 ?        00:00:00 /usr/bin/redis-server 127.0.0.1:6379                                        

Redis的冗余备份

在本文中,将介绍如何在多个 Redis 实例中进行复制,以建立 Redis 故障转移环境(第二部分)。

附录

iptables的更改

如果要从外部服务器连接到 Redis,请确保设置了 iptables。允许 IP 地址(可以指定范围)和 Redis 的端口,然后重新启动 iptables 服务以使更改生效。

$ sudo vi /etc/sysconfig/iptables
-A INPUT -p tcp -m tcp -s 128.0.0.0/24 --dport 6379 -j ACCEPT
$ sudo /etc/init.d/iptables restart

内存过量配置的设置

在Redis启动时,可能会在日志中显示以下消息。

# WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
    [15050] 16 Jan 22:17:28.303 * DB loaded from disk: 0.000 seconds

在Linux中,当实际内存不足且swap区也被用尽时,存在一种强制终止正在占用内存的进程的机制(称为OOMKiller)。

0:空き容量がなければ実行中のプロセスを強制終了する(デフォルト)
1:制限ギリギリまでメモリがあるように振る舞い、確保できなければ実行中のプロセスを強制終了する
2:空き容量がない場合はエラーを発生させる

当进行Redis的数据持久化(快照或AOF日志保存)时,它会使用存储数据两倍大小的内存。因此,如果内存用尽并且分配失败,将会发生错误。根据OOMKiller的设置,可能会强制终止Redis进程。

警告信息显示需要设置vm.overcommit_memory = 1,但原本应该引发错误并由应用程序捕获到错误,因此将其设置为”2″。(可能我对此有误解,请详细指导一下)

请注意,在更改系统设置文件之前,请先备份。另外,在更改之后需要重新启动服务器。

$ sudo cp -p /etc/sysctl.conf /etc/sysctl.conf_`date '+%Y%m%d'`
$ sudo vi /etc/sysctl.conf
vm.overcommit_memory = 2

$ sudo shutdown -r now

破解/crack@redis.io

近期有人公开了一种利用 Redis 命令 “config set dbfilename” 功能的攻击方法,通过 Redis 的启动用户权限可以任意创建文件。(类似于配置 SSH 公钥以打开远程登录漏洞)

关于Redis的攻击研究是由作者提供的。

原因是因为忘记了bind的设置,如果受到攻击,将会注册crackit作为键和ssh密钥以及crack@redis.io作为值。(一眼就能感受到危险)

验证与其他服务器的连接以及解除绑定设置(IP地址限制)后,重要的是不要忘记关闭。

对应的措施是:
1. 在 redis.conf 中通过 bind 参数限制 IP 地址(关闭)
指定可连接的服务器 IP 地址,并重新启动 Redis。

$ sudo vi /etc/redis/redis.conf
bind  127.0.0.1
$ sudo /etc/init.d/redis restart
    1. 用iptables关闭redis的端口

 

    仅指定可以访问redis端口的IP地址,并重新启动iptables
$ sudo vi /etc/sysconfig/iptables

 [IP帯域で許可する場合]
  -A INPUT -p tcp -m tcp -s [接続させるIP帯域] –dport 6379 -j ACCEPT

 [ポート閉塞する場合]
  6397の行をコメントアウト(もしくは6379関連は記載しない)

$ sudo /etc/init.d/iptables restart

以上 包含的内容如上 。

bannerAds