【编者的话】本文介绍了如何使用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下载,低版本会有问题)。

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

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

  1. 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基础镜像创建一个新的容器。

  1. 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命令。

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

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

  1. 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‘找到下面这一行, 并去掉注释。

  1. PermitRootLogin yes

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

  1. 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以及一些其它的工具。可以使用下面的命令:

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

首先,我们下载Redis 3.0.0 RC1。

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

解压这个包并make。

  1. 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/下面

  1. 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‘,然后启动它!

  1. 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的文件,像下面这样:

  1. 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文件里面,我们加入下面的内容:

  1. #!/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 ...’这个镜像到我们本地的库就可以了,像下面这样:

  1. 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

  1. 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,例如下面我们部署了三个实例:

  1. 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容器:

  1. 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服务器上面:

  1. 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的服务有没有起来:

  1. docker exec -t -i redis bash -l

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

  3. redis-server /etc/redis/redis.conf

6. 配置Redis的从节点



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



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

  1. 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地址,像下面这样:

  1. 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,如果配置正确的话会得到下面的结果:

  1. 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. alter table导致的mysql事务回滚失败

    今天做数据迁移, 发现事务有时候可以回滚, 有时候不可以回滚, 最后一点点调试发现中间有段修改表结构的语句, 最终导致回滚失败. 1.MySQL最常用的两个表类型: InnoDB和MyISAM.MyI ...

  2. 2016-2017-2 20155223 实验二 《Java面向对象程序设计》

    2016-2017-2 苏黄永郦 实验二 实验报告 前期准备工作--程序安装 -问题一 开始的时候我就在老师博客的指导下安装IDEA插件JUnit Generator V2.0.当然我的IDEA肯定没 ...

  3. Java反射API研究(4)——Class中的重要对象

    一.Constructor与Method的父类:Executable Executable表示一个可执行类,构造方法与普通方法都是Executable AnnotatedType[] getAnnot ...

  4. ASP Base64位 加密解密

    网上找了很多,运行时都会提示某个错误,有点乱.后面找到测试,这个转ASNI码的能实现 sBASE_64_CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabc ...

  5. 【.net】Dictionary<TKey, TValue>源码分析

    一图胜过千言万语~

  6. c# 利用t4模板,自动生成Model类

    我们在用ORM(比如dapper)的时候,很多时候都需要自己写Model层(当然也有很多orm框架自带了这种功能,比如ef),特别是表里字段比较多的时候,一个Model要写半天,而且Model如果用于 ...

  7. Aircrack-ng无线破解总结

    过年回来家,奈何没网,实属无奈,只好看破解教程,看能否破出来.于是总结如下 测试环境在linux平台下,我用的是ubuntu环境.ubuntu安装可以直接用sudo apt-get install a ...

  8. 小白学Linux

    Linux的文件关系: / 根最大的文件夹,存储此台计算机的所有数据 /etc  存放计算机的配置文件 /var/log 存放电脑的日志文件 /home 家的位置 路径:相对路径.绝对路径(从根下开始 ...

  9. Substrings(SPOJ8222) (sam(后缀自动机))

    You are given a string \(S\) which consists of 250000 lowercase latin letters at most. We define \(F ...

  10. [Objective-C语言教程]Posing(29)

    Posing,顾名思义,意思是“冒充”,它跟categories类似,但本质上不一样,Posing存在的目的在于子类可以冒充父类,使得后续的代码无需把父类修改为子类,就可以很方便的让父类表现成子类的行 ...