Docker搭建Redis主从模式

Docker安装Redis

  • 搜索镜像:docker search redis

  • 拉取镜像:docker pull redis

  • 启动容器(redis-master节点):docker run -p 16379:6379 --name redis-master -v /Users/lyb/Downloads/docker-volume/redis/master/data/:/data -v /Users/lyb/Downloads/docker-volume/redis/master/redis.conf:/etc/redis/redis.conf -d redis redis-server /etc/redis/redis.conf --appendonly yes

  • 启动容器(redis-slave-1节点):docker run -p 26379:6379 --name redis-slave-1 -v /Users/lyb/Downloads/docker-volume/redis/slave-1/data/:/data -v /Users/lyb/Downloads/docker-volume/redis/slave-1/redis.conf:/etc/redis/redis.conf -d redis redis-server /etc/redis/redis.conf --appendonly yes

  • 启动容器(redis-slave-2节点):docker run -p 36379:6379 --name redis-slave-2 -v /Users/lyb/Downloads/docker-volume/redis/slave-2/data/:/data -v /Users/lyb/Downloads/docker-volume/redis/slave-2/redis.conf:/etc/redis/redis.conf -d redis redis-server /etc/redis/redis.conf --appendonly yes

    • 参数说明:
      • -p:将容器内部端口映射到宿主机端口宿主机端口:容器内部端口
      • -v:挂载宿主机的一个目录宿主机目录:容器内部目录
      • -d:指定容器的运行模式,在运行容器时不会进入容器
      • redis:容器名称
      • redis-server /etc/redis/redis.conf --appendonly yes:容器启动时执行的命令指定了redis的配置文件,实际上配置文件是宿主机上挂载的位置
    • 注意事项:必须将redis.conf配置文件中的daemonize yes配置项注释,否则无法正常启动redis容器
  • 查看在运行的容器:

    lyb@lyb ~ % docker ps
    CONTAINER ID   IMAGE     COMMAND                  CREATED       STATUS          PORTS                     NAMES
    c325ca2a1fb0   redis     "docker-entrypoint.s…"   3 hours ago   Up 59 minutes   0.0.0.0:36379->6379/tcp   redis-slave-2
    7260a89e38b9   redis     "docker-entrypoint.s…"   3 hours ago   Up 59 minutes   0.0.0.0:26379->6379/tcp   redis-slave-1
    63f9fc52f834   redis     "docker-entrypoint.s…"   3 hours ago   Up 2 hours      0.0.0.0:16379->6379/tcp   redis-master
    lyb@lyb ~ % 
    

主从模式(简易模式)

注意,此种搭建模式在重启容器之后将被重置!!!

特点

  • 主数据库可以进行读写操作,当读写操作导致数据变化时会自动将数据同步给从数据库
  • 从数据库一般都是只读的,并且接收主数据库同步过来的数据
  • 一个master可以拥有多个slave,但是一个slave只能对应一个master
  • slave挂了不影响其他slave的读和master的读和写,重新启动后会将数据从master同步过来
  • master挂了以后,不影响slave的读,但redis不再提供写服务,master重启后redis将重新对外提供写服务
  • master挂了以后,不会在slave节点中重新选一个master

工作机制

  • 当slave启动后,主动向master发送SYNC命令。master接收到SYNC命令后在后台保存快照(RDB持久化)和缓存保存快照这段时间的命令,然后将保存的快照文件和缓存的命令发送给slave。slave接收到快照文件和命令后加载快照文件和缓存的执行命令。复制初始化后,master每次接收到的写命令都会同步发送给slave,保证主从数据一致性。

搭建

redis-master节点
  • 查看容器ip:docker inspect [CONTAINER ID]

    lyb@lyb ~ % docker inspect 63f9fc52f834
    [
        {
            "Id": "63f9fc52f8344bf07526ded7c4b3f2e38e77ba9a6569b6d82de6589eeba33aaf",
            "Created": "2021-04-15T06:06:59.3646836Z",
            "Path": "docker-entrypoint.sh",
            "Args": [
                "redis-server",
                "/etc/redis/redis.conf",
                "--appendonly",
                "yes"
            ],
            "State": {
                "Status": "running",
                "Running": true,
                "Paused": false,
                "Restarting": false,
                "OOMKilled": false,
                "Dead": false,
                "Pid": 10840,
                "ExitCode": 0,
                "Error": "",
                "StartedAt": "2021-04-15T07:28:50.579912Z",
                "FinishedAt": "2021-04-15T07:27:50.4797116Z"
            },
            "Image": "sha256:de974760ddb2f32dbddb74b7bb8cff4c1eee06d43d36d11bbca1dc815173916e",
            "ResolvConfPath": "/var/lib/docker/containers/63f9fc52f8344bf07526ded7c4b3f2e38e77ba9a6569b6d82de6589eeba33aaf/resolv.conf",
            "HostnamePath": "/var/lib/docker/containers/63f9fc52f8344bf07526ded7c4b3f2e38e77ba9a6569b6d82de6589eeba33aaf/hostname",
            "HostsPath": "/var/lib/docker/containers/63f9fc52f8344bf07526ded7c4b3f2e38e77ba9a6569b6d82de6589eeba33aaf/hosts",
            "LogPath": "/var/lib/docker/containers/63f9fc52f8344bf07526ded7c4b3f2e38e77ba9a6569b6d82de6589eeba33aaf/63f9fc52f8344bf07526ded7c4b3f2e38e77ba9a6569b6d82de6589eeba33aaf-json.log",
            "Name": "/redis-master",
            "RestartCount": 0,
            "Driver": "overlay2",
            "Platform": "linux",
            "MountLabel": "",
            "ProcessLabel": "",
            "AppArmorProfile": "",
            "ExecIDs": [
                "df966627604fe0253c4148ae11da4568edf868246d67d817e670f2e94a341b13"
            ],
            "HostConfig": {
                "Binds": [
                    "/Users/lyb/Downloads/docker-volume/redis/master/data/:/data",
                    "/Users/lyb/Downloads/docker-volume/redis/master/redis.conf:/etc/redis/redis.conf"
                ],
                "ContainerIDFile": "",
                "LogConfig": {
                    "Type": "json-file",
                    "Config": {}
                },
                "NetworkMode": "default",
                "PortBindings": {
                    "6379/tcp": [
                        {
                            "HostIp": "",
                            "HostPort": "16379"
                        }
                    ]
                },
                "RestartPolicy": {
                    "Name": "no",
                    "MaximumRetryCount": 0
                },
                "AutoRemove": false,
                "VolumeDriver": "",
                "VolumesFrom": null,
                "CapAdd": null,
                "CapDrop": null,
                "CgroupnsMode": "host",
                "Dns": [],
                "DnsOptions": [],
                "DnsSearch": [],
                "ExtraHosts": null,
                "GroupAdd": null,
                "IpcMode": "private",
                "Cgroup": "",
                "Links": null,
                "OomScoreAdj": 0,
                "PidMode": "",
                "Privileged": false,
                "PublishAllPorts": false,
                "ReadonlyRootfs": false,
                "SecurityOpt": null,
                "UTSMode": "",
                "UsernsMode": "",
                "ShmSize": 67108864,
                "Runtime": "runc",
                "ConsoleSize": [
                    0,
                    0
                ],
                "Isolation": "",
                "CpuShares": 0,
                "Memory": 0,
                "NanoCpus": 0,
                "CgroupParent": "",
                "BlkioWeight": 0,
                "BlkioWeightDevice": [],
                "BlkioDeviceReadBps": null,
                "BlkioDeviceWriteBps": null,
                "BlkioDeviceReadIOps": null,
                "BlkioDeviceWriteIOps": null,
                "CpuPeriod": 0,
                "CpuQuota": 0,
                "CpuRealtimePeriod": 0,
                "CpuRealtimeRuntime": 0,
                "CpusetCpus": "",
                "CpusetMems": "",
                "Devices": [],
                "DeviceCgroupRules": null,
                "DeviceRequests": null,
                "KernelMemory": 0,
                "KernelMemoryTCP": 0,
                "MemoryReservation": 0,
                "MemorySwap": 0,
                "MemorySwappiness": null,
                "OomKillDisable": false,
                "PidsLimit": null,
                "Ulimits": null,
                "CpuCount": 0,
                "CpuPercent": 0,
                "IOMaximumIOps": 0,
                "IOMaximumBandwidth": 0,
                "MaskedPaths": [
                    "/proc/asound",
                    "/proc/acpi",
                    "/proc/kcore",
                    "/proc/keys",
                    "/proc/latency_stats",
                    "/proc/timer_list",
                    "/proc/timer_stats",
                    "/proc/sched_debug",
                    "/proc/scsi",
                    "/sys/firmware"
                ],
                "ReadonlyPaths": [
                    "/proc/bus",
                    "/proc/fs",
                    "/proc/irq",
                    "/proc/sys",
                    "/proc/sysrq-trigger"
                ]
            },
            "GraphDriver": {
                "Data": {
                    "LowerDir": "/var/lib/docker/overlay2/ceb17051515a2a28f377c7b60f31ee5a103a54204646864fcee73af917a7076f-init/diff:/var/lib/docker/overlay2/e3bf4f9175538886770cf528920a0657bdaed37f6242c37a27f27a7e7122bf67/diff:/var/lib/docker/overlay2/92820d62871786226cd208e9083d8498c64bc01d54cd5e2b9ea33512b520dc1a/diff:/var/lib/docker/overlay2/e0358b5d10dcfa96424ac55a4339bca32460d194d679ae77b880c697e8398400/diff:/var/lib/docker/overlay2/72a31df794ef94f9e4d371a382572937c2bc10754a15c0d1345c1031518466ab/diff:/var/lib/docker/overlay2/2cbeeb1fe64364eb7e2f2afabda61d7ceb4d64bb94ff80b5414df1e201d8c9eb/diff:/var/lib/docker/overlay2/0dc7be964a5913b4843257560ec60fd24571132291024269c63ecc92767db067/diff",
                    "MergedDir": "/var/lib/docker/overlay2/ceb17051515a2a28f377c7b60f31ee5a103a54204646864fcee73af917a7076f/merged",
                    "UpperDir": "/var/lib/docker/overlay2/ceb17051515a2a28f377c7b60f31ee5a103a54204646864fcee73af917a7076f/diff",
                    "WorkDir": "/var/lib/docker/overlay2/ceb17051515a2a28f377c7b60f31ee5a103a54204646864fcee73af917a7076f/work"
                },
                "Name": "overlay2"
            },
            "Mounts": [
                {
                    "Type": "bind",
                    "Source": "/Users/lyb/Downloads/docker-volume/redis/master/data/",
                    "Destination": "/data",
                    "Mode": "",
                    "RW": true,
                    "Propagation": "rprivate"
                },
                {
                    "Type": "bind",
                    "Source": "/Users/lyb/Downloads/docker-volume/redis/master/redis.conf",
                    "Destination": "/etc/redis/redis.conf",
                    "Mode": "",
                    "RW": true,
                    "Propagation": "rprivate"
                }
            ],
            "Config": {
                "Hostname": "63f9fc52f834",
                "Domainname": "",
                "User": "",
                "AttachStdin": false,
                "AttachStdout": false,
                "AttachStderr": false,
                "ExposedPorts": {
                    "6379/tcp": {}
                },
                "Tty": false,
                "OpenStdin": false,
                "StdinOnce": false,
                "Env": [
                    "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                    "GOSU_VERSION=1.12",
                    "REDIS_VERSION=6.2.1",
                    "REDIS_DOWNLOAD_URL=http://download.redis.io/releases/redis-6.2.1.tar.gz",
                    "REDIS_DOWNLOAD_SHA=cd222505012cce20b25682fca931ec93bd21ae92cb4abfe742cf7b76aa907520"
                ],
                "Cmd": [
                    "redis-server",
                    "/etc/redis/redis.conf",
                    "--appendonly",
                    "yes"
                ],
                "Image": "redis",
                "Volumes": {
                    "/data": {}
                },
                "WorkingDir": "/data",
                "Entrypoint": [
                    "docker-entrypoint.sh"
                ],
                "OnBuild": null,
                "Labels": {}
            },
            "NetworkSettings": {
                "Bridge": "",
                "SandboxID": "811db9346ac517f5da91029dad23f6f0066907f15c7420a3dc16e0bf94b0bc4d",
                "HairpinMode": false,
                "LinkLocalIPv6Address": "",
                "LinkLocalIPv6PrefixLen": 0,
                "Ports": {
                    "6379/tcp": [
                        {
                            "HostIp": "0.0.0.0",
                            "HostPort": "16379"
                        }
                    ]
                },
                "SandboxKey": "/var/run/docker/netns/811db9346ac5",
                "SecondaryIPAddresses": null,
                "SecondaryIPv6Addresses": null,
                "EndpointID": "eb2600cbabf6677474f36f861ec4e2e2c4d473751318abf352a0922b21b56376",
                "Gateway": "172.17.0.1",
                "GlobalIPv6Address": "",
                "GlobalIPv6PrefixLen": 0,
                "IPAddress": "172.17.0.2",
                "IPPrefixLen": 16,
                "IPv6Gateway": "",
                "MacAddress": "02:42:ac:11:00:02",
                "Networks": {
                    "bridge": {
                        "IPAMConfig": null,
                        "Links": null,
                        "Aliases": null,
                        "NetworkID": "5095449becf8f1ceb55119eede50795bddf55038589f4fd0ba6fe7e8326aa7b2",
                        "EndpointID": "eb2600cbabf6677474f36f861ec4e2e2c4d473751318abf352a0922b21b56376",
                        "Gateway": "172.17.0.1",
                        "IPAddress": "172.17.0.2",
                        "IPPrefixLen": 16,
                        "IPv6Gateway": "",
                        "GlobalIPv6Address": "",
                        "GlobalIPv6PrefixLen": 0,
                        "MacAddress": "02:42:ac:11:00:02",
                        "DriverOpts": null
                    }
                }
            }
        }
    ]
    lyb@lyb ~ % 
    
  • 进入容器:docker exec -it [CONTAINER ID] redis-cli

    lyb@lyb ~ % docker exec -it 63f9fc52f834 redis-cli
    127.0.0.1:6379> 
    
  • 认证(如果配置了requirepass则需要认证):auth [PASSWORD]

  • 查看实例所属角色:role

    127.0.0.1:6379> role
    1) "master"
    2) (integer) 438
    3) (empty array)
    127.0.0.1:6379> 
    
  • 查看主从复制信息:info replication

    127.0.0.1:6379> info replication
    # Replication
    role:master
    connected_slaves:0
    master_failover_state:no-failover
    master_replid:c83b64bc28645c2b10085db020c668e4b184d0dd
    master_replid2:0000000000000000000000000000000000000000
    master_repl_offset:438
    second_repl_offset:-1
    repl_backlog_active:1
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:1
    repl_backlog_histlen:438
    127.0.0.1:6379> 
    
redis-slave-1节点
  • 查看容器ip:docker inspect [CONTAINER ID]

    lyb@lyb ~ % docker inspect 7260a89e38b9
    [
        {
            "Id": "7260a89e38b97c27e6f077e3afe9fe530acad33b46b753ab1fa06b20c6d18f8e",
            "Created": "2021-04-15T06:17:14.287864Z",
            "Path": "docker-entrypoint.sh",
            "Args": [
                "redis-server",
                "/etc/redis/redis.conf",
                "--appendonly",
                "yes"
            ],
            "State": {
                "Status": "running",
                "Running": true,
                "Paused": false,
                "Restarting": false,
                "OOMKilled": false,
                "Dead": false,
                "Pid": 11310,
                "ExitCode": 0,
                "Error": "",
                "StartedAt": "2021-04-15T08:14:53.8135887Z",
                "FinishedAt": "2021-04-15T08:14:13.762688Z"
            },
            "Image": "sha256:de974760ddb2f32dbddb74b7bb8cff4c1eee06d43d36d11bbca1dc815173916e",
            "ResolvConfPath": "/var/lib/docker/containers/7260a89e38b97c27e6f077e3afe9fe530acad33b46b753ab1fa06b20c6d18f8e/resolv.conf",
            "HostnamePath": "/var/lib/docker/containers/7260a89e38b97c27e6f077e3afe9fe530acad33b46b753ab1fa06b20c6d18f8e/hostname",
            "HostsPath": "/var/lib/docker/containers/7260a89e38b97c27e6f077e3afe9fe530acad33b46b753ab1fa06b20c6d18f8e/hosts",
            "LogPath": "/var/lib/docker/containers/7260a89e38b97c27e6f077e3afe9fe530acad33b46b753ab1fa06b20c6d18f8e/7260a89e38b97c27e6f077e3afe9fe530acad33b46b753ab1fa06b20c6d18f8e-json.log",
            "Name": "/redis-slave-1",
            "RestartCount": 0,
            "Driver": "overlay2",
            "Platform": "linux",
            "MountLabel": "",
            "ProcessLabel": "",
            "AppArmorProfile": "",
            "ExecIDs": [
                "7d197e7c9ae5cf90178879ed7687051bf1ee092cb3360a1b50c3ca5a3ba9e51b"
            ],
            "HostConfig": {
                "Binds": [
                    "/Users/lyb/Downloads/docker-volume/redis/slave-1/redis.conf:/etc/redis/redis.conf",
                    "/Users/lyb/Downloads/docker-volume/redis/slave-1/data/:/data"
                ],
                "ContainerIDFile": "",
                "LogConfig": {
                    "Type": "json-file",
                    "Config": {}
                },
                "NetworkMode": "default",
                "PortBindings": {
                    "6379/tcp": [
                        {
                            "HostIp": "",
                            "HostPort": "26379"
                        }
                    ]
                },
                "RestartPolicy": {
                    "Name": "no",
                    "MaximumRetryCount": 0
                },
                "AutoRemove": false,
                "VolumeDriver": "",
                "VolumesFrom": null,
                "CapAdd": null,
                "CapDrop": null,
                "CgroupnsMode": "host",
                "Dns": [],
                "DnsOptions": [],
                "DnsSearch": [],
                "ExtraHosts": null,
                "GroupAdd": null,
                "IpcMode": "private",
                "Cgroup": "",
                "Links": null,
                "OomScoreAdj": 0,
                "PidMode": "",
                "Privileged": false,
                "PublishAllPorts": false,
                "ReadonlyRootfs": false,
                "SecurityOpt": null,
                "UTSMode": "",
                "UsernsMode": "",
                "ShmSize": 67108864,
                "Runtime": "runc",
                "ConsoleSize": [
                    0,
                    0
                ],
                "Isolation": "",
                "CpuShares": 0,
                "Memory": 0,
                "NanoCpus": 0,
                "CgroupParent": "",
                "BlkioWeight": 0,
                "BlkioWeightDevice": [],
                "BlkioDeviceReadBps": null,
                "BlkioDeviceWriteBps": null,
                "BlkioDeviceReadIOps": null,
                "BlkioDeviceWriteIOps": null,
                "CpuPeriod": 0,
                "CpuQuota": 0,
                "CpuRealtimePeriod": 0,
                "CpuRealtimeRuntime": 0,
                "CpusetCpus": "",
                "CpusetMems": "",
                "Devices": [],
                "DeviceCgroupRules": null,
                "DeviceRequests": null,
                "KernelMemory": 0,
                "KernelMemoryTCP": 0,
                "MemoryReservation": 0,
                "MemorySwap": 0,
                "MemorySwappiness": null,
                "OomKillDisable": false,
                "PidsLimit": null,
                "Ulimits": null,
                "CpuCount": 0,
                "CpuPercent": 0,
                "IOMaximumIOps": 0,
                "IOMaximumBandwidth": 0,
                "MaskedPaths": [
                    "/proc/asound",
                    "/proc/acpi",
                    "/proc/kcore",
                    "/proc/keys",
                    "/proc/latency_stats",
                    "/proc/timer_list",
                    "/proc/timer_stats",
                    "/proc/sched_debug",
                    "/proc/scsi",
                    "/sys/firmware"
                ],
                "ReadonlyPaths": [
                    "/proc/bus",
                    "/proc/fs",
                    "/proc/irq",
                    "/proc/sys",
                    "/proc/sysrq-trigger"
                ]
            },
            "GraphDriver": {
                "Data": {
                    "LowerDir": "/var/lib/docker/overlay2/e6691173f9df0b95263ed197733b3dc32fcd4c72ea09276b2ce1ec6bbffe0c31-init/diff:/var/lib/docker/overlay2/e3bf4f9175538886770cf528920a0657bdaed37f6242c37a27f27a7e7122bf67/diff:/var/lib/docker/overlay2/92820d62871786226cd208e9083d8498c64bc01d54cd5e2b9ea33512b520dc1a/diff:/var/lib/docker/overlay2/e0358b5d10dcfa96424ac55a4339bca32460d194d679ae77b880c697e8398400/diff:/var/lib/docker/overlay2/72a31df794ef94f9e4d371a382572937c2bc10754a15c0d1345c1031518466ab/diff:/var/lib/docker/overlay2/2cbeeb1fe64364eb7e2f2afabda61d7ceb4d64bb94ff80b5414df1e201d8c9eb/diff:/var/lib/docker/overlay2/0dc7be964a5913b4843257560ec60fd24571132291024269c63ecc92767db067/diff",
                    "MergedDir": "/var/lib/docker/overlay2/e6691173f9df0b95263ed197733b3dc32fcd4c72ea09276b2ce1ec6bbffe0c31/merged",
                    "UpperDir": "/var/lib/docker/overlay2/e6691173f9df0b95263ed197733b3dc32fcd4c72ea09276b2ce1ec6bbffe0c31/diff",
                    "WorkDir": "/var/lib/docker/overlay2/e6691173f9df0b95263ed197733b3dc32fcd4c72ea09276b2ce1ec6bbffe0c31/work"
                },
                "Name": "overlay2"
            },
            "Mounts": [
                {
                    "Type": "bind",
                    "Source": "/Users/lyb/Downloads/docker-volume/redis/slave-1/redis.conf",
                    "Destination": "/etc/redis/redis.conf",
                    "Mode": "",
                    "RW": true,
                    "Propagation": "rprivate"
                },
                {
                    "Type": "bind",
                    "Source": "/Users/lyb/Downloads/docker-volume/redis/slave-1/data/",
                    "Destination": "/data",
                    "Mode": "",
                    "RW": true,
                    "Propagation": "rprivate"
                }
            ],
            "Config": {
                "Hostname": "7260a89e38b9",
                "Domainname": "",
                "User": "",
                "AttachStdin": false,
                "AttachStdout": false,
                "AttachStderr": false,
                "ExposedPorts": {
                    "6379/tcp": {}
                },
                "Tty": false,
                "OpenStdin": false,
                "StdinOnce": false,
                "Env": [
                    "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                    "GOSU_VERSION=1.12",
                    "REDIS_VERSION=6.2.1",
                    "REDIS_DOWNLOAD_URL=http://download.redis.io/releases/redis-6.2.1.tar.gz",
                    "REDIS_DOWNLOAD_SHA=cd222505012cce20b25682fca931ec93bd21ae92cb4abfe742cf7b76aa907520"
                ],
                "Cmd": [
                    "redis-server",
                    "/etc/redis/redis.conf",
                    "--appendonly",
                    "yes"
                ],
                "Image": "redis",
                "Volumes": {
                    "/data": {}
                },
                "WorkingDir": "/data",
                "Entrypoint": [
                    "docker-entrypoint.sh"
                ],
                "OnBuild": null,
                "Labels": {}
            },
            "NetworkSettings": {
                "Bridge": "",
                "SandboxID": "066bf65e4d2217757f8a45e26bfaf40550c945b056efa5332562992bfbba8563",
                "HairpinMode": false,
                "LinkLocalIPv6Address": "",
                "LinkLocalIPv6PrefixLen": 0,
                "Ports": {
                    "6379/tcp": [
                        {
                            "HostIp": "0.0.0.0",
                            "HostPort": "26379"
                        }
                    ]
                },
                "SandboxKey": "/var/run/docker/netns/066bf65e4d22",
                "SecondaryIPAddresses": null,
                "SecondaryIPv6Addresses": null,
                "EndpointID": "f870267c7851fc8175231367519a5330cad59a5a3da716cdb6dcad963b48e0e7",
                "Gateway": "172.17.0.1",
                "GlobalIPv6Address": "",
                "GlobalIPv6PrefixLen": 0,
                "IPAddress": "172.17.0.3",
                "IPPrefixLen": 16,
                "IPv6Gateway": "",
                "MacAddress": "02:42:ac:11:00:03",
                "Networks": {
                    "bridge": {
                        "IPAMConfig": null,
                        "Links": null,
                        "Aliases": null,
                        "NetworkID": "5095449becf8f1ceb55119eede50795bddf55038589f4fd0ba6fe7e8326aa7b2",
                        "EndpointID": "f870267c7851fc8175231367519a5330cad59a5a3da716cdb6dcad963b48e0e7",
                        "Gateway": "172.17.0.1",
                        "IPAddress": "172.17.0.3",
                        "IPPrefixLen": 16,
                        "IPv6Gateway": "",
                        "GlobalIPv6Address": "",
                        "GlobalIPv6PrefixLen": 0,
                        "MacAddress": "02:42:ac:11:00:03",
                        "DriverOpts": null
                    }
                }
            }
        }
    ]
    lyb@lyb ~ % 
    
  • 进入容器:docker exec -it [CONTAINER ID] redis-cli

    lyb@lyb ~ % docker exec -it 7260a89e38b9 redis-cli
    127.0.0.1:6379> 
    
  • 认证(如果配置了requirepass则需要认证):auth [PASSWORD]

  • 查看实例所属角色:role

    127.0.0.1:6379> role
    1) "master"
    2) (integer) 0
    3) (empty array)
    127.0.0.1:6379> 
    
  • 查看主从复制信息:info replication

    127.0.0.1:6379> info replication
    # Replication
    role:master
    connected_slaves:0
    master_failover_state:no-failover
    master_replid:788cd48377afaf297ef5060101fa0c6b572b6e02
    master_replid2:0000000000000000000000000000000000000000
    master_repl_offset:0
    second_repl_offset:-1
    repl_backlog_active:0
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:0
    repl_backlog_histlen:0
    127.0.0.1:6379> 
    
  • 设置主实例的密码(如果主实例配置了requirepass则需要设置):config set masterauth [MASTER-REDIS PASSWORD]

  • 将该节点设置为主节点的从属节点(注意:这里使用的IP和PORT是容器内部的,可以通过docker inspect [CONTAINER ID]命令查看):slaveof REDIS-MASTER-IP REDIS-MASTER-PORT

    127.0.0.1:6379> slaveof 172.17.0.2 6379
    OK
    
    • 将从属节点重置为主节点:slaveof no one
  • 此时在次查看子节点的角色信息和主从复制信息:

    127.0.0.1:6379> role
    1) "slave"
    2) "172.17.0.2"
    3) (integer) 6379
    4) "connected"
    5) (integer) 1037
    127.0.0.1:6379> info replication
    # Replication
    role:slave
    master_host:172.17.0.2
    master_port:6379
    master_link_status:up
    master_last_io_seconds_ago:10
    master_sync_in_progress:0
    slave_repl_offset:1037
    slave_priority:100
    slave_read_only:1
    connected_slaves:0
    master_failover_state:no-failover
    master_replid:c83b64bc28645c2b10085db020c668e4b184d0dd
    master_replid2:0000000000000000000000000000000000000000
    master_repl_offset:1037
    second_repl_offset:-1
    repl_backlog_active:1
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:439
    repl_backlog_histlen:599
    127.0.0.1:6379> 
    
redis-slave-2节点
  • 查看容器ip:docker inspect [CONTAINER ID]

    lyb@lyb ~ % docker inspect c325ca2a1fb0
    [
        {
            "Id": "c325ca2a1fb04cc5002f4798330232b0dbe6e1c76eb1636243e02d5a59d56bf4",
            "Created": "2021-04-15T06:25:05.7932522Z",
            "Path": "docker-entrypoint.sh",
            "Args": [
                "redis-server",
                "/etc/redis/redis.conf",
                "--appendonly",
                "yes"
            ],
            "State": {
                "Status": "running",
                "Running": true,
                "Paused": false,
                "Restarting": false,
                "OOMKilled": false,
                "Dead": false,
                "Pid": 11481,
                "ExitCode": 0,
                "Error": "",
                "StartedAt": "2021-04-15T08:14:58.918656Z",
                "FinishedAt": "2021-04-15T08:14:19.2969766Z"
            },
            "Image": "sha256:de974760ddb2f32dbddb74b7bb8cff4c1eee06d43d36d11bbca1dc815173916e",
            "ResolvConfPath": "/var/lib/docker/containers/c325ca2a1fb04cc5002f4798330232b0dbe6e1c76eb1636243e02d5a59d56bf4/resolv.conf",
            "HostnamePath": "/var/lib/docker/containers/c325ca2a1fb04cc5002f4798330232b0dbe6e1c76eb1636243e02d5a59d56bf4/hostname",
            "HostsPath": "/var/lib/docker/containers/c325ca2a1fb04cc5002f4798330232b0dbe6e1c76eb1636243e02d5a59d56bf4/hosts",
            "LogPath": "/var/lib/docker/containers/c325ca2a1fb04cc5002f4798330232b0dbe6e1c76eb1636243e02d5a59d56bf4/c325ca2a1fb04cc5002f4798330232b0dbe6e1c76eb1636243e02d5a59d56bf4-json.log",
            "Name": "/redis-slave-2",
            "RestartCount": 0,
            "Driver": "overlay2",
            "Platform": "linux",
            "MountLabel": "",
            "ProcessLabel": "",
            "AppArmorProfile": "",
            "ExecIDs": [
                "da748cc03257bca73def48f9405d542f06cf50e40e65de2913c55d4330339922"
            ],
            "HostConfig": {
                "Binds": [
                    "/Users/lyb/Downloads/docker-volume/redis/slave-2/data/:/data",
                    "/Users/lyb/Downloads/docker-volume/redis/slave-2/redis.conf:/etc/redis/redis.conf"
                ],
                "ContainerIDFile": "",
                "LogConfig": {
                    "Type": "json-file",
                    "Config": {}
                },
                "NetworkMode": "default",
                "PortBindings": {
                    "6379/tcp": [
                        {
                            "HostIp": "",
                            "HostPort": "36379"
                        }
                    ]
                },
                "RestartPolicy": {
                    "Name": "no",
                    "MaximumRetryCount": 0
                },
                "AutoRemove": false,
                "VolumeDriver": "",
                "VolumesFrom": null,
                "CapAdd": null,
                "CapDrop": null,
                "CgroupnsMode": "host",
                "Dns": [],
                "DnsOptions": [],
                "DnsSearch": [],
                "ExtraHosts": null,
                "GroupAdd": null,
                "IpcMode": "private",
                "Cgroup": "",
                "Links": null,
                "OomScoreAdj": 0,
                "PidMode": "",
                "Privileged": false,
                "PublishAllPorts": false,
                "ReadonlyRootfs": false,
                "SecurityOpt": null,
                "UTSMode": "",
                "UsernsMode": "",
                "ShmSize": 67108864,
                "Runtime": "runc",
                "ConsoleSize": [
                    0,
                    0
                ],
                "Isolation": "",
                "CpuShares": 0,
                "Memory": 0,
                "NanoCpus": 0,
                "CgroupParent": "",
                "BlkioWeight": 0,
                "BlkioWeightDevice": [],
                "BlkioDeviceReadBps": null,
                "BlkioDeviceWriteBps": null,
                "BlkioDeviceReadIOps": null,
                "BlkioDeviceWriteIOps": null,
                "CpuPeriod": 0,
                "CpuQuota": 0,
                "CpuRealtimePeriod": 0,
                "CpuRealtimeRuntime": 0,
                "CpusetCpus": "",
                "CpusetMems": "",
                "Devices": [],
                "DeviceCgroupRules": null,
                "DeviceRequests": null,
                "KernelMemory": 0,
                "KernelMemoryTCP": 0,
                "MemoryReservation": 0,
                "MemorySwap": 0,
                "MemorySwappiness": null,
                "OomKillDisable": false,
                "PidsLimit": null,
                "Ulimits": null,
                "CpuCount": 0,
                "CpuPercent": 0,
                "IOMaximumIOps": 0,
                "IOMaximumBandwidth": 0,
                "MaskedPaths": [
                    "/proc/asound",
                    "/proc/acpi",
                    "/proc/kcore",
                    "/proc/keys",
                    "/proc/latency_stats",
                    "/proc/timer_list",
                    "/proc/timer_stats",
                    "/proc/sched_debug",
                    "/proc/scsi",
                    "/sys/firmware"
                ],
                "ReadonlyPaths": [
                    "/proc/bus",
                    "/proc/fs",
                    "/proc/irq",
                    "/proc/sys",
                    "/proc/sysrq-trigger"
                ]
            },
            "GraphDriver": {
                "Data": {
                    "LowerDir": "/var/lib/docker/overlay2/d6e3aa9f075e8eb874b991246d64a1d95bd97a4a6a78a9628c6e703ba28f61aa-init/diff:/var/lib/docker/overlay2/e3bf4f9175538886770cf528920a0657bdaed37f6242c37a27f27a7e7122bf67/diff:/var/lib/docker/overlay2/92820d62871786226cd208e9083d8498c64bc01d54cd5e2b9ea33512b520dc1a/diff:/var/lib/docker/overlay2/e0358b5d10dcfa96424ac55a4339bca32460d194d679ae77b880c697e8398400/diff:/var/lib/docker/overlay2/72a31df794ef94f9e4d371a382572937c2bc10754a15c0d1345c1031518466ab/diff:/var/lib/docker/overlay2/2cbeeb1fe64364eb7e2f2afabda61d7ceb4d64bb94ff80b5414df1e201d8c9eb/diff:/var/lib/docker/overlay2/0dc7be964a5913b4843257560ec60fd24571132291024269c63ecc92767db067/diff",
                    "MergedDir": "/var/lib/docker/overlay2/d6e3aa9f075e8eb874b991246d64a1d95bd97a4a6a78a9628c6e703ba28f61aa/merged",
                    "UpperDir": "/var/lib/docker/overlay2/d6e3aa9f075e8eb874b991246d64a1d95bd97a4a6a78a9628c6e703ba28f61aa/diff",
                    "WorkDir": "/var/lib/docker/overlay2/d6e3aa9f075e8eb874b991246d64a1d95bd97a4a6a78a9628c6e703ba28f61aa/work"
                },
                "Name": "overlay2"
            },
            "Mounts": [
                {
                    "Type": "bind",
                    "Source": "/Users/lyb/Downloads/docker-volume/redis/slave-2/data/",
                    "Destination": "/data",
                    "Mode": "",
                    "RW": true,
                    "Propagation": "rprivate"
                },
                {
                    "Type": "bind",
                    "Source": "/Users/lyb/Downloads/docker-volume/redis/slave-2/redis.conf",
                    "Destination": "/etc/redis/redis.conf",
                    "Mode": "",
                    "RW": true,
                    "Propagation": "rprivate"
                }
            ],
            "Config": {
                "Hostname": "c325ca2a1fb0",
                "Domainname": "",
                "User": "",
                "AttachStdin": false,
                "AttachStdout": false,
                "AttachStderr": false,
                "ExposedPorts": {
                    "6379/tcp": {}
                },
                "Tty": false,
                "OpenStdin": false,
                "StdinOnce": false,
                "Env": [
                    "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                    "GOSU_VERSION=1.12",
                    "REDIS_VERSION=6.2.1",
                    "REDIS_DOWNLOAD_URL=http://download.redis.io/releases/redis-6.2.1.tar.gz",
                    "REDIS_DOWNLOAD_SHA=cd222505012cce20b25682fca931ec93bd21ae92cb4abfe742cf7b76aa907520"
                ],
                "Cmd": [
                    "redis-server",
                    "/etc/redis/redis.conf",
                    "--appendonly",
                    "yes"
                ],
                "Image": "redis",
                "Volumes": {
                    "/data": {}
                },
                "WorkingDir": "/data",
                "Entrypoint": [
                    "docker-entrypoint.sh"
                ],
                "OnBuild": null,
                "Labels": {}
            },
            "NetworkSettings": {
                "Bridge": "",
                "SandboxID": "41767dcadd5466978fda65bdd75e5ad917b4ee1f2accf162b4a89cfa7081f768",
                "HairpinMode": false,
                "LinkLocalIPv6Address": "",
                "LinkLocalIPv6PrefixLen": 0,
                "Ports": {
                    "6379/tcp": [
                        {
                            "HostIp": "0.0.0.0",
                            "HostPort": "36379"
                        }
                    ]
                },
                "SandboxKey": "/var/run/docker/netns/41767dcadd54",
                "SecondaryIPAddresses": null,
                "SecondaryIPv6Addresses": null,
                "EndpointID": "644f54aa63bf243971c502ba751356384c46f4da69921e1de407fc7f17b8cf2b",
                "Gateway": "172.17.0.1",
                "GlobalIPv6Address": "",
                "GlobalIPv6PrefixLen": 0,
                "IPAddress": "172.17.0.4",
                "IPPrefixLen": 16,
                "IPv6Gateway": "",
                "MacAddress": "02:42:ac:11:00:04",
                "Networks": {
                    "bridge": {
                        "IPAMConfig": null,
                        "Links": null,
                        "Aliases": null,
                        "NetworkID": "5095449becf8f1ceb55119eede50795bddf55038589f4fd0ba6fe7e8326aa7b2",
                        "EndpointID": "644f54aa63bf243971c502ba751356384c46f4da69921e1de407fc7f17b8cf2b",
                        "Gateway": "172.17.0.1",
                        "IPAddress": "172.17.0.4",
                        "IPPrefixLen": 16,
                        "IPv6Gateway": "",
                        "GlobalIPv6Address": "",
                        "GlobalIPv6PrefixLen": 0,
                        "MacAddress": "02:42:ac:11:00:04",
                        "DriverOpts": null
                    }
                }
            }
        }
    ]
    lyb@lyb ~ % 
    
  • 进入容器:docker exec -it [CONTAINER ID] redis-cli

    lyb@lyb ~ % docker exec -it c325ca2a1fb0 redis-cli
    127.0.0.1:6379> 
    
  • 认证(如果配置了requirepass则需要认证):auth [PASSWORD]

  • 查看实例所属角色:role

    127.0.0.1:6379> role
    1) "master"
    2) (integer) 0
    3) (empty array)
    127.0.0.1:6379> 
    
  • 查看主从复制信息:info replication

    127.0.0.1:6379> info replication
    # Replication
    role:master
    connected_slaves:0
    master_failover_state:no-failover
    master_replid:b12a5ddf95f1c20606eecb632e9c2ad6b2f29bb9
    master_replid2:0000000000000000000000000000000000000000
    master_repl_offset:0
    second_repl_offset:-1
    repl_backlog_active:0
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:0
    repl_backlog_histlen:0
    127.0.0.1:6379> 
    
  • 设置主实例的密码(如果主实例配置了requirepass则需要设置):config set masterauth [MASTER-REDIS PASSWORD]

  • 将该节点设置为主节点的从属节点(注意:这里使用的IP和PORT是容器内部的,可以通过docker inspect [CONTAINER ID]命令查看):slaveof REDIS-MASTER-IP REDIS-MASTER-PORT

    127.0.0.1:6379> slaveof 172.17.0.2 6379
    OK
    
    • 将从属节点重置为主节点:slaveof no one
  • 此时在次查看子节点的角色信息和主从复制信息:

    127.0.0.1:6379> role
    1) "slave"
    2) "172.17.0.2"
    3) (integer) 6379
    4) "connected"
    5) (integer) 1583
    127.0.0.1:6379> info replication
    # Replication
    role:slave
    master_host:172.17.0.2
    master_port:6379
    master_link_status:up
    master_last_io_seconds_ago:0
    master_sync_in_progress:0
    slave_repl_offset:1639
    slave_priority:100
    slave_read_only:1
    connected_slaves:0
    master_failover_state:no-failover
    master_replid:c83b64bc28645c2b10085db020c668e4b184d0dd
    master_replid2:0000000000000000000000000000000000000000
    master_repl_offset:1639
    second_repl_offset:-1
    repl_backlog_active:1
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:1584
    repl_backlog_histlen:56
    127.0.0.1:6379> 
    

验证

  • 通过以上步骤就已经实现了一主两重复制模式,此时在此查看主节点的角色和主从复制信息:

    127.0.0.1:6379> role
    1) "master"
    2) (integer) 2577
    3) 1) 1) "172.17.0.3"
          2) "6379"
          3) "2577"
       2) 1) "172.17.0.4"
          2) "6379"
          3) "2577"
    127.0.0.1:6379> info replication
    # Replication
    role:master
    connected_slaves:2
    slave0:ip=172.17.0.3,port=6379,state=online,offset=2577,lag=1
    slave1:ip=172.17.0.4,port=6379,state=online,offset=2577,lag=1
    master_failover_state:no-failover
    master_replid:c83b64bc28645c2b10085db020c668e4b184d0dd
    master_replid2:0000000000000000000000000000000000000000
    master_repl_offset:2577
    second_repl_offset:-1
    repl_backlog_active:1
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:1
    repl_backlog_histlen:2577
    127.0.0.1:6379> 
    

    可以看到,已经有两个slave节点

  • 在主节点中存入数据,在两个子节点中分别获取:

    # 在redis-master节点中存入数据
    127.0.0.1:6379> set message 'i am master node.'
    OK
    127.0.0.1:6379> 
    
    # 在redis-slave-1节点中获取数据
    127.0.0.1:6379> get message
    "i am master node."
    127.0.0.1:6379> 
    
    # 在redis-slave-2节点中获取数据
    127.0.0.1:6379> get message
    "i am master node."
    127.0.0.1:6379> 
    

    至此主从复制模式搭建完毕。

主从模式

此种搭建模式重启容器会不会被重置,如果还要继续搭建哨兵模式推荐选择使用该种模式。

  • redis-master配置文件:

    # 允许所有ip地址访问
    bind 0.0.0.0
    
    # 以守护进程的方式运行,就是关闭了远程连接窗口,redis依然运行,使用容器时必须注释,否则启动容器失败
    # daemonize yes
    
    # 设置需要密码才能访问
    requirepass root
    
    # 设置redis持久化,默认是no
    appendonly yes
    
    # 设置主节点的密码(当主节点设置了requirepass配置时需要配置该项或者需要搭建哨兵模式的时候也需要配置该项,因为如果主节宕机重启之后就会#  # 装换为slave节点,这个时候需要去连接sentinel选举出来的新的master节点)
    # masterauth root
    
  • redis-slave-1节点配置文件:

    # 允许所有ip地址访问
    bind 0.0.0.0
    
    # 以守护进程的方式运行,就是关闭了远程连接窗口,redis依然运行,使用容器时必须注释,否则启动容器失败
    # daemonize yes
    
    # 设置需要密码才能访问
    requirepass root
    
    # 设置redis持久化,默认是no
    appendonly yes
    
    # 设置主节点的密码(当主节点设置了requirepass配置时需要配置该项)
    masterauth root
    
    # 主从模式下主节点的IP和PORT(这里要根据实际情况来定,我这里使用的是容器内部的IP和端口)
    # 这里也可以使用容器的名称,使用容器名称的时候在构建容器的时候就需要使用--link参数
    # 这里也可以使用物理地址,使用物理地址的时候在构建容器的时候就需要使用--net参数
    replicaof 172.17.0.2 6379
    
  • redis-slave-2节点配置文件:

    # 允许所有ip地址访问
    bind 0.0.0.0
    
    # 以守护进程的方式运行,就是关闭了远程连接窗口,redis依然运行,使用容器时必须注释,否则启动容器失败
    # daemonize yes
    
    # 设置需要密码才能访问
    requirepass root
    
    # 设置redis持久化,默认是no
    appendonly yes
    
    # 设置主节点的密码(当主节点设置了requirepass配置时需要配置该项)
    masterauth root
    
    # 主从模式下主节点的IP和PORT(这里要根据实际情况来定,我这里使用的是容器内部的IP和端口)
    # 这里也可以使用容器的名称,使用容器名称的时候在构建容器的时候就需要使用--link参数
    # 这里也可以使用物理地址,使用物理地址的时候在构建容器的时候就需要使用--net参数
    replicaof 172.17.0.2 6379
    
  • 重启容器:docker restart redis-master redis-slave-1 redis-slave-2

    lyb@lyb ~ % docker restart redis-master redis-slave-1 redis-slave-2
    redis-master
    redis-slave-1
    redis-slave-2
    lyb@lyb ~ % 
    

    重启之后通过验证可以发现通过修改配置文件的方式搭建主从模式在重启容器之后不会被重置。

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐