【编者的话】本文介绍了如何使用Docker搭建Redis集群,很多读者都在问Docker能带来哪些实质性的好处,我想本文就是一个很好的例子。不使用Docker你也可以搭建Redis集群,那使用Docker后会有怎么样的优势了?我想可以用两个词总结:快速和复用。

海量技术文章:http://tieba.yunxunmi.com/

云搜 http://so.yunxunmi.com/ 让搜索更简单 采用html5完全支持手机和PC



我们经常会遇到这样一个问题:当我们想进行一个完整的测试的时候,往往缺少硬件或者其它资源。为了满足需求,我可能需要三台服务,或者说三个虚拟机。但是我发现我们没有时间来创建它们,并且如果要物理机的话我们也没有那么多资源。这也是为什么我对Docker如此感兴趣,因为它可以解决我的问题。



我想在Ubuntu上创建三个运行RedisDocker容器,并把它们连接起来,然后我就可以自由的在测试和开发过程中水平的扩展了, 接下来我就给你们展示我是怎么做的,以及这样做的优势。



1. 下载和配置基础镜像



我使用的是非常优秀的phusion镜像作为基础镜像,它增加了很多Docker忽略的特性, 比如按序启动服务等等, 关于这个镜像的更多信息,可以点击这里了解。



首先,让我们使用Docker来pullphusion镜像(译者注:建议使用高版本的Docker下载,低版本会有问题)。

root@server:/home/sam# docker pull phusion/baseimage

下载完成之后, 你可以通过docker images命令看到最新下载的镜像。

root@server:/home/sam# docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
phusion/baseimage 0.9.15 cf39b476aeec 3 months ago 289.4 MB
phusion/baseimage latest cf39b476aeec 3 months ago 289.4 MB

这个镜像非常好用,你可以在容器启动的时候指定特定服务的启动顺序, 在这里我想给这个镜像加一个SSH密码登录的功能,而不是使用SSH key。因为是在本地运行,所以不用太担心安全的问题。我们需要创建一个phusion的实例, 然后通过SSH key登录, 并且修改配置,重启SSH,之后我们就可以使用root登录了。



首先,用phusion基础镜像创建一个新的容器。

root@server:/home/sam# docker run -d --name redis phusion/baseimage /sbin/my_init 
--enable-insecure-key

/sbin/my_init是允许phusion在容器启动的时候启动你的服务。enable-insecure-key允许我们使用‘insecure key‘ssh进新的容器。



现在我们已经部署了容器, 接下来需要得到它的IP地址,可以使用docker inspect命令。

root@server:/home/sam# docker inspect redis | grep IPA
"IPAddress": "172.17.0.46",

接下来,下载’insecure key‘并使用它登录这个容器。

root@server:/home/sam# curl -o insecure_key -fSL https://github.com/phusion/baseimage-docker/raw/master/image/insecure_key
root@server:/home/sam# chmod 600 insecure_key
root@server:/home/sam# ssh -i insecure_key root@<IP address>
The authenticity of host '172.17.0.52 (172.17.0.52)' can't be established.
ECDSA key fingerprint is aa:bb:cc:xx:xx:xx:xx:xx:xx:xx:xx:yy:zz:04:bf:04.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '172.17.0.52' (ECDSA) to the list of known hosts.
root@c36b4bba7dd4:~#

祝贺你, 你现在SSH进入容器了!下面你需要修改SSH,从而我们不再需要’insecure key‘了,为了做到这个,打开’/etc/ssh/sshd_config‘找到下面这一行, 并去掉注释。

PermitRootLogin yes

保存文件, 我们再设置root的密码。

root@c36b4bba7dd4:~# passwd
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
root@c36b4bba7dd4:~#

以上我们做了一些准备工作,接下来我们将在这个容器中安装Redis。



2 安装Redis



现在我们已经有了配置好的镜像了,接下来我们需要去下载和安装Redis,你可以从这里下载到你想要的Redis,在我们的例子中用到的是3.0.0 RC1,下载地址是:https://github.com/antirez/red ... ar.gz。



注意:你还需要安装wget、gcc、make以及一些其它的工具。可以使用下面的命令:

apt-get update  #更新系统
apt-get upgrade #升级系统
apt-get install wget gcc make#安装wget、gcc、make

首先,我们下载Redis 3.0.0 RC1。

root@e3919192d9e3:/home# wget https://github.com/antirez/redis/archive/3.0.0-rc1.tar.gz

解压这个包并make。

root@e3919192d9e3:/home# tar -zxvf 3.0.0-rc1.tar.gz
root@e3919192d9e3:/home# cd redis-3.0.0-rc1/
root@e3919192d9e3:/home/redis-3.0.0-rc1# make

最后, 我们把编译好的代码中的几个可执行命令移动到/usr/bin/下面

root@e3919192d9e3:/home/redis-3.0.0-rc1# cd src
root@e3919192d9e3:/home/redis-3.0.0-rc1/src# mv redis-cli redis-server redis-sentinel /usr/bin/
root@e3919192d9e3:/home/redis-3.0.0-rc1/src# cd ..
root@e3919192d9e3:/home/redis-3.0.0-rc1# mkdir -p /etc/redis/
root@e3919192d9e3:/home/redis-3.0.0-rc1# cp redis.conf /etc/redis/redis.conf

现在打开文件/etc/redis/redis.conf, 找到‘daemonize no’改为‘daemonize yes‘,然后启动它!

root@e3919192d9e3:/home/redis-3.0.0-rc1/src# redis-server /etc/redis/redis.conf
root@e3919192d9e3:/home/redis-3.0.0-rc1/src#

好了, Redis现在已经安装好了,并且在容器里面运行了,使用的配置文件是/etc/redis/redis.conf。



3. 让Docker在启动容器的时候启动Redis服务



现在我们的容器正在运行Redis,并且也可以使用SSH登录了,我们还需要让它在容器启动的时候自动启动Redis服务,使用phusion基础镜像来实现这点相当的容易。首先,因为我们启动容器的时候使用了/sibn/my_init, 它会去运行任何我们放在/etc/service/*下面的程序。所以,对于我们来说,我们只要去创建一个目录以及在这个目录里面再创建一个叫run的文件,像下面这样:

root@e3919192d9e3:/etc/service# cd /etc/service
root@e3919192d9e3:/etc/service# mkdir redis
root@e3919192d9e3:/etc/service# cd redis
root@e3919192d9e3:/etc/service/redis# nano run

在这个run文件里面,我们加入下面的内容:

#!/bin/sh
set -e
exec /usr/bin/redis-server /etc/redis/redis.conf

海量技术文章:http://tieba.yunxunmi.com/

云搜 http://so.yunxunmi.com/ 让搜索更简单 采用html5完全支持手机和PC

最后,记得给run文件添加可执行权限。



4. 提交镜像以便于重用



现在我们的redis容器运行良好, 我们想要把它保存为伪模板,以便在Docker上重复部署。做到这个非常简单,我们只要使用‘docker commit ...’这个镜像到我们本地的库就可以了,像下面这样:

root@server:/home/sam# docker ps -as
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES SIZE
e3919192d9e3 phusion/baseimage:0.9.15 "/sbin/my_init --ena 3 hours ago Up 3 hours redis 164.9 MB
root@server:/home/sam# docker commit redis redis-cluster-node
root@server:/home/sam# docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
redis-cluster-node latest babfb02edf4d 5 hours ago 561.2 MB

5. 部署新镜像的3个实例

为了解释清楚,我会删除之前创建的容器,以免后面搞晕。首先使用docker stop
redis
,之后再docker rm redis

root@server:/home/sam# docker stop redis
redis
root@server:/home/sam# docker rm redis
redis
root@server:/home/sam#

很简单,下面让我们部署新镜像的3个实例,我们使用了Docker的端口映射机制,从而我们就可以使用Host服务器的IP访问这些实例,我们给这些实例关联的端口如下:



node1 - hostip:7001

node2 - hostip:7002

node3 - hostip:7003



所以我们运行redis-cli -h 192.168.0.2 -p 7001,它将重定向到172.17.0.x -p 6379,例如下面我们部署了三个实例:

root@server:/home/sam# docker run -d --name node1 -p 7001:6379 redis-cluster-node /sbin/my_init
cd1c1f96346bdf9c1cec04333c2e849992ecbc4375dcea6b30902dd9842d8c99
root@server:/home/sam# docker run -d --name node2 -p 7002:6379 redis-cluster-node /sbin/my_init
cd1c1f96346bdf9c1cec04333c2e849992ecbc4375dcea6b30902dd9842d8c99
root@server:/home/sam# docker run -d --name node3 -p 7003:6379 redis-cluster-node /sbin/my_init
cd1c1f96346bdf9c1cec04333c2e849992ecbc4375dcea6b30902dd9842d8c99
root@server:/home/sam#

现在我们可以运行docker ps -as来查看我们运行的三个Redis容器:

root@server:/home/sam# docker ps -as
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES SIZE
a532b4ac60d9 redis-cluster-node:latest "/sbin/my_init" 5 hours ago Up 5 hours 0.0.0.0:7003->6379/tcp node3 2.267 MB
6c8a87a0a76a redis-cluster-node:latest "/sbin/my_init" 5 hours ago Up 5 hours 0.0.0.0:7002->6379/tcp node2 2.318 MB
39e02633ccf8 redis-cluster-node:latest "/sbin/my_init" 5 hours ago Up 5 hours 0.0.0.0:7001->6379/tcp node1 2.334 MB
root@server:/home/sam#

现在我们看到了3个容器,分别名字为node1、node2和node3,并且有一个专门的端口与Redis 服务的端口相映射。为了测试这样的映射是正确的,可以在另外一台机器使用redis-cli登录到各个Redis服务器上面:

root@server:/home/sam# redis-cli -h 192.168.0.2 -p 7001
redis 192.168.0.16:7001>
root@server:/home/sam# redis-cli -h 192.168.0.2 -p 7002
redis 192.168.0.16:7002>
root@server:/home/sam# redis-cli -h 192.168.0.2 -p 7003
redis 192.168.0.16:7003>
root@server:/home/sam# redis-cli -h 192.168.0.2 -p 7005
Could not connect to Redis at 192.168.0.2:7005: Connection refused
not connected>

正如你看到的, 我们可以使用 hostip+port登录到对应的Redis服务器上, 当我们尝试一个不正确的端口时,却不行。

http://tieba.yunxunmi.com/tieba-Redis.html

译者增加: 如果这里验证失败了的可以登录进容器中检查下Redis的服务有没有起来:

docker exec -t -i redis bash -l

netstat -anp | grep redis #看看有没有网络监听,如果没有执行下面的命令启动redis服务

redis-server /etc/redis/redis.conf

6. 配置Redis的从节点



我们有了三个独立的Redis服务器, 现在我们想把它们连接到一起, 从而我们可以测试这个集群的扩展性,对集群的监控,或者是做其它的事情。



我们把node1作为主节点,把node2和node3配置为它的从节点,这可以简单的通过修改/etc/redis/redis.conf这个文件来实现。SSH进入node2和node3节点,修改配置文件,然后重启容器:

root@server:/home/sam# docker inspect node1 | grep IPA
"IPAddress": "172.17.0.46",
root@server:/home/sam# docker inspect node2 | grep IPA
"IPAddress": "172.17.0.47",
root@server:/home/sam# ssh root@172.17.0.47
root@172.17.0.47's password:
Last login: Tue Jan 13 11:47:31 2015 from 172.17.42.1
root@6c8a87a0a76a:~# nano /etc/redis/redis.conf

http://tieba.yunxunmi.com/tieba-Redis.html

在这个配置文件中我们只要找到‘salveof’这一行,然后去掉注释,修改为node1的ip地址,像下面这样:

root@6c8a87a0a76a:~# cat /etc/redis/redis.conf | grep slaveof
# Master-Slave replication. Use slaveof to make a Redis instance a copy of
slaveof 172.17.0.46 6379
root@6c8a87a0a76a:~#

最后使用命令docker restart node2重启容器, 现在它就是node1的一个从节点了。为了验证这个, 使用redis-cli分别登录到node1和node2, 在node1上运行命令set
hello world
, 然后在node2上运行get hello,如果配置正确的话会得到下面的结果:

root@server:/home/sam# redis-cli -h 192.168.0.16 -p 7001
redis 192.168.0.12:7001> set hello world
OK
redis 192.168.0.12:7001> exit
root@server:/home/sam# redis-cli -h 192.168.0.16 -p 7002
redis 192.168.0.12:7002> get hello
"world"
redis 192.168.0.12:7002> exit
root@server:/home/sam#

对于node3也做同样的配置即可。



恭喜,基于Docker的、拥有三个节点且可水平扩展的Redis集群就这样搭好了。



接下来的下一篇博客中,我将给大家展示如何使用Opsview去监控Redis集群,你可以看到一个像下面这样展示你的集群统计信息的可视化界面:

http://tieba.yunxunmi.com/tieba-Redis.html

海量技术文章:http://tieba.yunxunmi.com/

云搜 http://so.yunxunmi.com/ 让搜索更简单 采用html5完全支持手机和PC

更多docker相关:http://tieba.yunxunmi.com/tieba-docker-pn-3.html

用Docker构建分布式Redis集群的更多相关文章

  1. Windows10+Docker搭建分布式Redis集群(一)

    摘要,Docker for Windows 仅支持专业版 目录 第一步:检查系统支持虚拟化 第二步:下载Docker对应版本 第三步:配置镜像加速 第一步:检查系统是否支持虚拟化 Docker前提是需 ...

  2. Windows10+Docker搭建分布式Redis集群(SSH服务镜像)(二)

    前言:上篇文章我们搭建好了Docker,下面我们开始使用Docker创建镜像,Docker命令就不介绍了.这里宿主是Windows10,cmd的管理和后期文件的复制不是很方便,将创建支持SSH的Cen ...

  3. Docker镜像配置redis集群

    redis版本:3.2.3 架构: 3节点redis集群,并为每个节点设置一个备用节点,共6个节点 1.安装redis镜像 docker load < docker.redis.tar.gz 2 ...

  4. 从零开始学习docker之在docker中搭建redis(集群)

    docker搭建redis集群 docker-compose是以多容器的方式启动,非常适合用来启动集群 一.环境准备 云环境:CentOS 7.6 64位 二.安装docker-compose #需要 ...

  5. 【docker】【redis】2.docker上设置redis集群---Redis Cluster部署【集群服务】【解决在docker中redis启动后,状态为Restarting,日志报错:Configured to not listen anywhere, exiting.问题】【Waiting for the cluster to join...问题】

    参考地址:https://www.cnblogs.com/zhoujinyi/p/6477133.html https://www.cnblogs.com/cxbhakim/p/9151720.htm ...

  6. docker下安装redis集群

    docker-compose.yml master: image: redis:4 container_name: redis-cluster_master command: redis-server ...

  7. 分布式ID系列(4)——Redis集群实现的分布式ID适合做分布式ID吗

    首先是项目地址: https://github.com/maqiankun/distributed-id-redis-generator 关于Redis集群生成分布式ID,这里要先了解redis使用l ...

  8. redis集群(Sentinel)

    问题 Redis 主哨兵模式是如何保证高可用的 主要依赖主哨兵的发现故障和故障转移 概述 本文假设读者对redis 的主从复制已经进行了了解 . Redis 主哨兵集群为Redis 提供了高可用,即高 ...

  9. Redis集群功能概述

    在单机Redis中介绍过Redis的复制特性以及Redis Sentinel和twemproxy,其中: 复制:可以创建指定服务器的复制品,这些复制品可以用户扩展系统处理读请求的能力: Redis S ...

随机推荐

  1. HDU 5117 Fluorescent (数学+状压DP)

    题意:有 n 个灯,初始状态都是关闭,有m个开关,每个开关都控制若干个.问在m个开关按下与否的2^m的情况中,求每种情况下亮灯数量的立方和. 析:首先,如果直接做的话,时间复杂度无法接受,所以要对其进 ...

  2. metasploitable实践

    使用Fimap和metasploitable2文件包含漏洞测试 fimap 首先查看msf已经存在的漏洞: root@kali:~# fimap -u 'http://192.168.136.130/ ...

  3. oracle 索引的分类

    1. B树索引(默认索引,保存讲过排序过的索引列和对应的rowid值) 1)说明: 1.oracle中最常用的索引:B树索引就是一颗二叉树:叶子节点(双向链表)包含索引列和指向表中每个匹配行的ROWI ...

  4. TogetherJS本地部署,基于websocket的网页即时视频、语音、文字聊天

    TogetherJS分为两大部分,一个是hu文件夹中的服务端:另外一个是TogetherJS文件夹中的Together.JS文件,包含了所有的网页文字.语音等操作. 需要预先安装Node.js,可以百 ...

  5. 洛谷P1486 [NOI2004]郁闷的出纳员(splay)

    题目描述 OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常调整员工的工资 ...

  6. 窗口间传送数据wsprintf,WM_SETTEXT,SendMessage的理解

    对wsprintf  API函数的理解: int wsprintf ( LPTSTR lpOut, // pointer to buffer for output  LPCTSTR lpFmt, // ...

  7. Media change : please insert the disk labeled

    在Debian中使用apt-get安装软件包时经常会提示让你插入netinst的光盘: Media change: please insert the disc labeled 当没有时就无法进行安装 ...

  8. 【Oracle 12c】CUUG OCP认证071考试原题解析(32)

    32.choose the best answer View the Exhibit and examine the data in EMP and DEPT tables. In the DEPT ...

  9. enumerate 和 dict.items()

    对 list 遍历 a_list = [1,2,3] for index,iterm in enumerate(a_list): print(index,iterm) 对 dict 遍历 dict = ...

  10. 【文文殿下】对后缀自动机(SAM)的理解

    后缀自动机,是一种数据结构,是由状态和转移关系构成的.它虽然叫做后缀自动机,可是他却与后缀并没有什么太大的联系. 后缀自动机的每一种状态都是原串的一些子串的集合,每个子串只唯一存在于某个状态中,对每一 ...