如果您想了解redis哨兵集群、docker入门和redis哨兵集群配置的知识,那么本篇文章将是您的不二之选。我们将深入剖析redis哨兵集群、docker入门的各个方面,并为您解答redis哨兵集群
如果您想了解redis 哨兵集群、docker 入门和redis哨兵集群配置的知识,那么本篇文章将是您的不二之选。我们将深入剖析redis 哨兵集群、docker 入门的各个方面,并为您解答redis哨兵集群配置的疑在这篇文章中,我们将为您介绍redis 哨兵集群、docker 入门的相关知识,同时也会详细的解释redis哨兵集群配置的运用方法,并给出实际的案例分析,希望能帮助到您!
本文目录一览:- redis 哨兵集群、docker 入门(redis哨兵集群配置)
- (六) Docker 部署 Redis 高可用集群 (sentinel 哨兵模式)
- 11.Redis 哨兵集群实现高可用
- 110 redis 的哨兵集群 redis-cluster docker 安装
- 6.docker 学习笔记之入门,Redis - 哨兵机制理论
redis 哨兵集群、docker 入门(redis哨兵集群配置)
redis-sentinel 主从复制高可用
Redis-Sentinel
Redis-Sentinel 是 redis 官方推荐的高可用性解决方案,
当用 redis 作 master-slave 的高可用时,如果 master 本身宕机,redis 本身或者客户端都没有实现主从切换的功能。
而 redis-sentinel 就是一个独立运行的进程,用于监控多个 master-slave 集群,
自动发现 master 宕机,进行自动切换 slave > master。
sentinel 主要功能
不时的监控 redis 是否良好运行,如果节点不可达就会对节点进行下线标识
如果被标识的是主节点,sentinel 就会和其他的 sentinel 节点 “协商”,如果其他节点也人为主节点不可达,就会选举一个 sentinel 节点来完成自动故障转义
在 master-slave 进行切换后,master_redis.conf、slave_redis.conf 和 sentinel.conf 的内容都会发生改变,即 master_redis.conf 中会多一行 slaveof 的配置,sentinel.conf 的监控目标会随之调换
Sentinel 的工作方式


每个Sentinel以每秒钟一次的频率向它所知的Master,Slave以及其他 Sentinel 实例发送一个 PING 命令
如果一个实例(instance)距离最后一次有效回复 PING 命令的时间超过 down-after-milliseconds 选项所指定的值, 则这个实例会被 Sentinel 标记为主观下线。
如果一个Master被标记为主观下线,则正在监视这个Master的所有 Sentinel 要以每秒一次的频率确认Master的确进入了主观下线状态。
当有足够数量的 Sentinel(大于等于配置文件指定的值)在指定的时间范围内确认Master的确进入了主观下线状态, 则Master会被标记为客观下线
在一般情况下, 每个 Sentinel 会以每 10 秒一次的频率向它已知的所有Master,Slave发送 INFO 命令
当Master被 Sentinel 标记为客观下线时,Sentinel 向下线的 Master 的所有 Slave 发送 INFO 命令的频率会从 10 秒一次改为每秒一次
若没有足够数量的 Sentinel 同意 Master 已经下线, Master 的客观下线状态就会被移除。
若 Master 重新向 Sentinel 的 PING 命令返回有效回复, Master 的主观下线状态就会被移除。
主观下线和客观下线
主观下线:Subjectively Down,简称 SDOWN,指的是当前 Sentinel 实例对某个redis服务器做出的下线判断。
客观下线:Objectively Down, 简称 ODOWN,指的是多个 Sentinel 实例在对Master Server做出 SDOWN 判断,并且通过 SENTINEL is-master-down-by-addr 命令互相交流之后,得出的Master Server下线判断,然后开启failover.
SDOWN适合于Master和Slave,只要一个 Sentinel 发现Master进入了ODOWN, 这个 Sentinel 就可能会被其他 Sentinel 推选出, 并对下线的主服务器执行自动故障迁移操作。
ODOWN只适用于Master,对于Slave的 Redis 实例,Sentinel 在将它们判断为下线前不需要进行协商, 所以Slave的 Sentinel 永远不会达到ODOWN。
sentinel公作方式
redis 主从复制背景问题
Redis
主从复制可将主节点数据同步给从节点,从节点此时有两个作用:
- 一旦主节点宕机,从节点作为主节点的备份可以随时顶上来。
- 扩展主节点的读能力,分担主节点读压力。
但是问题是:
- 一旦主节点宕机,从节点上位,那么需要人为修改所有应用方的主节点地址(改为新的 master 地址),还需要命令所有从节点复制新的主节点
那么这个问题,redis-sentinel 就可以解决了
主从复制架构
Redis Sentinel 架构
redis 的一个进程,但是不存储数据,只是监控 redis
redis 命令整理
官网地址:http://redisdoc.com/
redis-cli info #查看redis数据库信息
redis-cli info replication #查看redis的复制授权信息
redis-cli info sentinel #查看redis的哨兵信息
安装与配置
服务器环境,一台即可完成操作
准备三个redis实例,一主两从
redis-6379.conf
[root@qishione sb]# cat redis-6379.conf
port 6379
daemonize yes
logfile "6379.log"
dbfilename "dump-6379.rdb"
dir "/var/redis/data/"
redis-6380.conf
[root@qishione sb]# cat redis-6380.conf
port 6380
daemonize yes
logfile "6380.log"
dbfilename "dump-6380.rdb"
dir "/var/redis/data/"
slaveof 127.0.0.1 6379
redis-6381.conf
[root@qishione sb]# cat redis-6381.conf
port 6381
daemonize yes
logfile "6381.log"
dbfilename "dump-6381.rdb"
dir "/var/redis/data/"
slaveof 127.0.0.1 6379
准备好了三个数据库实例,启动三个数据库实例
redis-server redis-6379.conf
redis-server redis-6380.conf
redis-server redis-6381.conf


# Redis 配置文件
# 当配置中需要配置内存大小时,可以使用 1k, 5GB, 4M 等类似的格式,其转换方式如下(不区分大小写)
#
# 1k => 1000 bytes
# 1kb => 1024 bytes
# 1m => 1000000 bytes
# 1mb => 1024*1024 bytes
# 1g => 1000000000 bytes
# 1gb => 1024*1024*1024 bytes
#
# 内存配置大小写是一样的.比如 1gb 1Gb 1GB 1gB
# daemonize no 默认情况下,redis不是在后台运行的,如果需要在后台运行,把该项的值更改为yes
daemonize yes
# 当redis在后台运行的时候,Redis默认会把pid文件放在/var/run/redis.pid,你可以配置到其他地址。
# 当运行多个redis服务时,需要指定不同的pid文件和端口
pidfile /var/run/redis.pid
# 指定redis运行的端口,默认是6379
port 6379
# 指定redis只接收来自于该IP地址的请求,如果不进行设置,那么将处理所有请求,
# 在生产环境中最好设置该项
# bind 127.0.0.1
# Specify the path for the unix socket that will be used to listen for
# incoming connections. There is no default, so Redis will not listen
# on a unix socket when not specified.
#
# unixsocket /tmp/redis.sock
# unixsocketperm 755
# 设置客户端连接时的超时时间,单位为秒。当客户端在这段时间内没有发出任何指令,那么关闭该连接
# 0是关闭此设置
timeout 0
# 指定日志记录级别
# Redis总共支持四个级别:debug、verbose、notice、warning,默认为verbose
# debug 记录很多信息,用于开发和测试
# varbose 有用的信息,不像debug会记录那么多
# notice 普通的verbose,常用于生产环境
# warning 只有非常重要或者严重的信息会记录到日志
loglevel debug
# 配置log文件地址
# 默认值为stdout,标准输出,若后台模式会输出到/dev/null
#logfile stdout
logfile /var/log/redis/redis.log
# To enable logging to the system logger, just set ''syslog-enabled'' to yes,
# and optionally update the other syslog parameters to suit your needs.
# syslog-enabled no
# Specify the syslog identity.
# syslog-ident redis
# Specify the syslog facility. Must be USER or between LOCAL0-LOCAL7.
# syslog-facility local0
# 可用数据库数
# 默认值为16,默认数据库为0,数据库范围在0-(database-1)之间
databases 16
################################ 快照 #################################
#
# 保存数据到磁盘,格式如下:
#
# save <seconds> <changes>
#
# 指出在多长时间内,有多少次更新操作,就将数据同步到数据文件rdb。
# 相当于条件触发抓取快照,这个可以多个条件配合
#
# 比如默认配置文件中的设置,就设置了三个条件
#
# save 900 1 900秒内至少有1个key被改变
# save 300 10 300秒内至少有300个key被改变
# save 60 10000 60秒内至少有10000个key被改变
save 900 1
save 300 10
save 60 10000
# 存储至本地数据库时(持久化到rdb文件)是否压缩数据,默认为yes
rdbcompression yes
# 本地持久化数据库文件名,默认值为dump.rdb
dbfilename dump.rdb
# 工作目录
#
# 数据库镜像备份的文件放置的路径。
# 这里的路径跟文件名要分开配置是因为redis在进行备份时,先会将当前数据库的状态写入到一个临时文件中,等备份完成时,
# 再把该该临时文件替换为上面所指定的文件,而这里的临时文件和上面所配置的备份文件都会放在这个指定的路径当中。
#
# AOF文件也会存放在这个目录下面
#
# 注意这里必须制定一个目录而不是文件
dir ./
################################# 复制 #################################
# 主从复制. 设置该数据库为其他数据库的从数据库.
# 设置当本机为slav服务时,设置master服务的IP地址及端口,在Redis启动时,它会自动从master进行数据同步
#
# slaveof <masterip> <masterport>
# 当master服务设置了密码保护时(用requirepass制定的密码)
# slav服务连接master的密码
#
# masterauth <master-password>
# 当从库同主机失去连接或者复制正在进行,从机库有两种运行方式:
#
# 1) 如果slave-serve-stale-data设置为yes(默认设置),从库会继续相应客户端的请求
#
# 2) 如果slave-serve-stale-data是指为no,出去INFO和SLAVOF命令之外的任何请求都会返回一个
# 错误"SYNC with master in progress"
#
slave-serve-stale-data yes
# 从库会按照一个时间间隔向主库发送PINGs.可以通过repl-ping-slave-period设置这个时间间隔,默认是10秒
#
# repl-ping-slave-period 10
# repl-timeout 设置主库批量数据传输时间或者ping回复时间间隔,默认值是60秒
# 一定要确保repl-timeout大于repl-ping-slave-period
# repl-timeout 60
################################## 安全 ###################################
# 设置客户端连接后进行任何其他指定前需要使用的密码。
# 警告:因为redis速度相当快,所以在一台比较好的服务器下,一个外部的用户可以在一秒钟进行150K次的密码尝试,这意味着你需要指定非常非常强大的密码来防止暴力破解
#
# requirepass foobared
# 命令重命名.
#
# 在一个共享环境下可以重命名相对危险的命令。比如把CONFIG重名为一个不容易猜测的字符。
#
# 举例:
#
# rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c52
#
# 如果想删除一个命令,直接把它重命名为一个空字符""即可,如下:
#
# rename-command CONFIG ""
################################### 约束 ####################################
# 设置同一时间最大客户端连接数,默认无限制,Redis可以同时打开的客户端连接数为Redis进程可以打开的最大文件描述符数,
# 如果设置 maxclients 0,表示不作限制。
# 当客户端连接数到达限制时,Redis会关闭新的连接并向客户端返回max number of clients reached错误信息
#
# maxclients 128
# 指定Redis最大内存限制,Redis在启动时会把数据加载到内存中,达到最大内存后,Redis会先尝试清除已到期或即将到期的Key
# Redis同时也会移除空的list对象
#
# 当此方法处理后,仍然到达最大内存设置,将无法再进行写入操作,但仍然可以进行读取操作
#
# 注意:Redis新的vm机制,会把Key存放内存,Value会存放在swap区
#
# maxmemory的设置比较适合于把redis当作于类似memcached的缓存来使用,而不适合当做一个真实的DB。
# 当把Redis当做一个真实的数据库使用的时候,内存使用将是一个很大的开销
# maxmemory <bytes>
# 当内存达到最大值的时候Redis会选择删除哪些数据?有五种方式可供选择
#
# volatile-lru -> 利用LRU算法移除设置过过期时间的key (LRU:最近使用 Least Recently Used )
# allkeys-lru -> 利用LRU算法移除任何key
# volatile-random -> 移除设置过过期时间的随机key
# allkeys->random -> remove a random key, any key
# volatile-ttl -> 移除即将过期的key(minor TTL)
# noeviction -> 不移除任何可以,只是返回一个写错误
#
# 注意:对于上面的策略,如果没有合适的key可以移除,当写的时候Redis会返回一个错误
#
# 写命令包括: set setnx setex append
# incr decr rpush lpush rpushx lpushx linsert lset rpoplpush sadd
# sinter sinterstore sunion sunionstore sdiff sdiffstore zadd zincrby
# zunionstore zinterstore hset hsetnx hmset hincrby incrby decrby
# getset mset msetnx exec sort
#
# 默认是:
#
# maxmemory-policy volatile-lru
# LRU 和 minimal TTL 算法都不是精准的算法,但是相对精确的算法(为了节省内存),随意你可以选择样本大小进行检测。
# Redis默认的灰选择3个样本进行检测,你可以通过maxmemory-samples进行设置
#
# maxmemory-samples 3
############################## AOF ###############################
# 默认情况下,redis会在后台异步的把数据库镜像备份到磁盘,但是该备份是非常耗时的,而且备份也不能很频繁,如果发生诸如拉闸限电、拔插头等状况,那么将造成比较大范围的数据丢失。
# 所以redis提供了另外一种更加高效的数据库备份及灾难恢复方式。
# 开启append only模式之后,redis会把所接收到的每一次写操作请求都追加到appendonly.aof文件中,当redis重新启动时,会从该文件恢复出之前的状态。
# 但是这样会造成appendonly.aof文件过大,所以redis还支持了BGREWRITEAOF指令,对appendonly.aof 进行重新整理。
# 你可以同时开启asynchronous dumps 和 AOF
appendonly no
# AOF文件名称 (默认: "appendonly.aof")
# appendfilename appendonly.aof
# Redis支持三种同步AOF文件的策略:
#
# no: 不进行同步,系统去操作 . Faster.
# always: always表示每次有写操作都进行同步. Slow, Safest.
# everysec: 表示对写操作进行累积,每秒同步一次. Compromise.
#
# 默认是"everysec",按照速度和安全折中这是最好的。
# 如果想让Redis能更高效的运行,你也可以设置为"no",让操作系统决定什么时候去执行
# 或者相反想让数据更安全你也可以设置为"always"
#
# 如果不确定就用 "everysec".
# appendfsync always
appendfsync everysec
# appendfsync no
# AOF策略设置为always或者everysec时,后台处理进程(后台保存或者AOF日志重写)会执行大量的I/O操作
# 在某些Linux配置中会阻止过长的fsync()请求。注意现在没有任何修复,即使fsync在另外一个线程进行处理
#
# 为了减缓这个问题,可以设置下面这个参数no-appendfsync-on-rewrite
#
# This means that while another child is saving the durability of Redis is
# the same as "appendfsync none", that in pratical terms means that it is
# possible to lost up to 30 seconds of log in the worst scenario (with the
# default Linux settings).
#
# If you have latency problems turn this to "yes". Otherwise leave it as
# "no" that is the safest pick from the point of view of durability.
no-appendfsync-on-rewrite no
# Automatic rewrite of the append only file.
# AOF 自动重写
# 当AOF文件增长到一定大小的时候Redis能够调用 BGREWRITEAOF 对日志文件进行重写
#
# 它是这样工作的:Redis会记住上次进行些日志后文件的大小(如果从开机以来还没进行过重写,那日子大小在开机的时候确定)
#
# 基础大小会同现在的大小进行比较。如果现在的大小比基础大小大制定的百分比,重写功能将启动
# 同时需要指定一个最小大小用于AOF重写,这个用于阻止即使文件很小但是增长幅度很大也去重写AOF文件的情况
# 设置 percentage 为0就关闭这个特性
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
################################## SLOW LOG ###################################
# Redis Slow Log 记录超过特定执行时间的命令。执行时间不包括I/O计算比如连接客户端,返回结果等,只是命令执行时间
#
# 可以通过两个参数设置slow log:一个是告诉Redis执行超过多少时间被记录的参数slowlog-log-slower-than(微妙),
# 另一个是slow log 的长度。当一个新命令被记录的时候最早的命令将被从队列中移除
# 下面的时间以微妙微单位,因此1000000代表一分钟。
# 注意制定一个负数将关闭慢日志,而设置为0将强制每个命令都会记录
slowlog-log-slower-than 10000
# 对日志长度没有限制,只是要注意它会消耗内存
# 可以通过 SLOWLOG RESET 回收被慢日志消耗的内存
slowlog-max-len 1024
################################ VM ###############################
### WARNING! Virtual Memory is deprecated in Redis 2.4
### The use of Virtual Memory is strongly discouraged.
# Virtual Memory allows Redis to work with datasets bigger than the actual
# amount of RAM needed to hold the whole dataset in memory.
# In order to do so very used keys are taken in memory while the other keys
# are swapped into a swap file, similarly to what operating systems do
# with memory pages.
#
# To enable VM just set ''vm-enabled'' to yes, and set the following three
# VM parameters accordingly to your needs.
vm-enabled no
# vm-enabled yes
# This is the path of the Redis swap file. As you can guess, swap files
# can''t be shared by different Redis instances, so make sure to use a swap
# file for every redis process you are running. Redis will complain if the
# swap file is already in use.
#
# The best kind of storage for the Redis swap file (that''s accessed at random)
# is a Solid State Disk (SSD).
#
# *** WARNING *** if you are using a shared hosting the default of putting
# the swap file under /tmp is not secure. Create a dir with access granted
# only to Redis user and configure Redis to create the swap file there.
vm-swap-file /tmp/redis.swap
# vm-max-memory configures the VM to use at max the specified amount of
# RAM. Everything that deos not fit will be swapped on disk *if* possible, that
# is, if there is still enough contiguous space in the swap file.
#
# With vm-max-memory 0 the system will swap everything it can. Not a good
# default, just specify the max amount of RAM you can in bytes, but it''s
# better to leave some margin. For instance specify an amount of RAM
# that''s more or less between 60 and 80% of your free RAM.
vm-max-memory 0
# Redis swap files is split into pages. An object can be saved using multiple
# contiguous pages, but pages can''t be shared between different objects.
# So if your page is too big, small objects swapped out on disk will waste
# a lot of space. If you page is too small, there is less space in the swap
# file (assuming you configured the same number of total swap file pages).
#
# If you use a lot of small objects, use a page size of 64 or 32 bytes.
# If you use a lot of big objects, use a bigger page size.
# If unsure, use the default :)
vm-page-size 32
# Number of total memory pages in the swap file.
# Given that the page table (a bitmap of free/used pages) is taken in memory,
# every 8 pages on disk will consume 1 byte of RAM.
#
# The total swap size is vm-page-size * vm-pages
#
# With the default of 32-bytes memory pages and 134217728 pages Redis will
# use a 4 GB swap file, that will use 16 MB of RAM for the page table.
#
# It''s better to use the smallest acceptable value for your application,
# but the default is large in order to work in most conditions.
vm-pages 134217728
# Max number of VM I/O threads running at the same time.
# This threads are used to read/write data from/to swap file, since they
# also encode and decode objects from disk to memory or the reverse, a bigger
# number of threads can help with big objects even if they can''t help with
# I/O itself as the physical device may not be able to couple with many
# reads/writes operations at the same time.
#
# The special value of 0 turn off threaded I/O and enables the blocking
# Virtual Memory implementation.
vm-max-threads 4
############################### ADVANCED CONFIG ###############################
# 当hash中包含超过指定元素个数并且最大的元素没有超过临界时,
# hash将以一种特殊的编码方式(大大减少内存使用)来存储,这里可以设置这两个临界值
# Redis Hash对应Value内部实际就是一个HashMap,实际这里会有2种不同实现,
# 这个Hash的成员比较少时Redis为了节省内存会采用类似一维数组的方式来紧凑存储,而不会采用真正的HashMap结构,对应的value redisObject的encoding为zipmap,
# 当成员数量增大时会自动转成真正的HashMap,此时encoding为ht。
hash-max-zipmap-entries 512
hash-max-zipmap-value 64
# list数据类型多少节点以下会采用去指针的紧凑存储格式。
# list数据类型节点值大小小于多少字节会采用紧凑存储格式。
list-max-ziplist-entries 512
list-max-ziplist-value 64
# set数据类型内部数据如果全部是数值型,且包含多少节点以下会采用紧凑格式存储。
set-max-intset-entries 512
# zsort数据类型多少节点以下会采用去指针的紧凑存储格式。
# zsort数据类型节点值大小小于多少字节会采用紧凑存储格式。
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
# Redis将在每100毫秒时使用1毫秒的CPU时间来对redis的hash表进行重新hash,可以降低内存的使用
#
# 当你的使用场景中,有非常严格的实时性需要,不能够接受Redis时不时的对请求有2毫秒的延迟的话,把这项配置为no。
#
# 如果没有这么严格的实时性要求,可以设置为yes,以便能够尽可能快的释放内存
activerehashing yes
################################## INCLUDES ###################################
# 指定包含其它的配置文件,可以在同一主机上多个Redis实例之间使用同一份配置文件,而同时各个实例又拥有自己的特定配置文件
# include /path/to/local.conf
# include /path/to/other.conf
redis.conf详解--补充--
此时可以在 master 上写入数据,在 slave 上查看数据,此时主从复制配置完成
开始配置 Redis Sentinel
准备三个配置文件,哨兵文件
// Sentinel节点的端口
redis-26379.conf
port 26379
dir /var/redis/data/
logfile "26379.log"
// 当前Sentinel节点监控 192.168.119.10:6379 这个主节点
// 2代表判断主节点失败至少需要2个Sentinel节点节点同意
// qsmaster是主节点的别名
sentinel monitor qsmaster 127.0.0.1 6379 2
sentinel down-after-milliseconds qsmaster 30000
sentinel parallel-syncs qsmaster 1
sentinel failover-timeout qsmaster 180000
daemonize yes
redis-26380.conf
port 26380
dir /var/redis/data/
logfile "26380.log"
sentinel monitor qsmaster 127.0.0.1 6379 2
//每个Sentinel节点都要定期PING命令来判断Redis数据节点和其余Sentinel节点是否可达,如果超过30000毫秒30s且没有回复,则判定不可达
sentinel down-after-milliseconds qsmaster 30000
//当Sentinel节点集合对主节点故障判定达成一致时,Sentinel领导者节点会做故障转移操作,选出新的主节点,
原来的从节点会向新的主节点发起复制操作,限制每次向新的主节点发起复制操作的从节点个数为1
sentinel parallel-syncs qsmaster 1
//故障转移超时时间为180000毫秒
sentinel failover-timeout qsmaster 180000
daemonize yes
redis-26381.conf
port 26381
dir /var/redis/data/
logfile "26381.log"
sentinel monitor qsmaster 127.0.0.1 6379 2
sentinel down-after-milliseconds qsmaster 30000
sentinel parallel-syncs qsmaster 1
sentinel failover-timeout qsmaster 180000
daemonize yes
redis-sentinel-26380.conf 和 redis-sentinel-26381.conf 的配置仅仅差异是 port (端口) 的不同。
启动三个哨兵实例
redis-sentinel redis-26379.conf
redis-sentinel redis-26380.conf
redis-sentinel redis-26381.conf
注意!!如果发现实验不成功,需删掉所有的哨兵配置文件,从新来过
注意!!如果发现实验不成功,需删掉所有的哨兵配置文件,从新来过
注意!!如果发现实验不成功,需删掉所有的哨兵配置文件,从新来过
检查哨兵状态是否正常
redis-cli -p 26379 info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=qsmaster,status=ok,address=127.0.0.1:6380,slaves=2,sentinels=3
看到最后一条信息正确即成功了哨兵,哨兵主节点名字叫做qsmaster,状态ok,监控地址是127.0.0.1:6380,有两个从节点,3个哨兵
redis 高可用故障实验
1.干掉6379的redis数据库
2.查看6380和6381的身份信息,是否自动的进行主从切换
3.手动启动6379挂掉的数据库,查看是否会被哨兵,添加进信息的主从集群(redis-cli -p 6379 info replication)
为什么要用 redis-cluster
并发问题
redis 官方生成可以达到 10 万 / 每秒,每秒执行 10 万条命令
假如业务需要每秒 100 万的命令执行呢?
数据量太大
一台服务器内存正常是 16~256G,假如你的业务需要 500G 内存,你怎么办?解决方案如下
- 配置一个超级牛逼的计算机,超大内存,超强 cpu,但是问题是。。。。
2. 正确的应该是考虑分布式,加机器,把数据分到不同的位置,分摊集中式的压力,一堆机器做一件事
客户端分片
redis 实例集群主要思想是将 redis 数据的 key 进行散列,通过 hash 函数特定的 key 会映射到指定的 redis 节点上
数据分布理论
分布式数据库首要解决把整个数据集按照分区规则映射到多个节点的问题,即把数据集划分到多个节点上,每个节点负责整个数据的一个子集。
常见的分区规则有哈希分区和顺序分区。Redis Cluster
采用哈希分区规则,因此接下来会讨论哈希分区规则。
- 节点取余分区
- 一致性哈希分区
- 虚拟槽分区 (redis-cluster 采用的方式)
顺序分区
哈希分区
节点取余
例如按照节点取余的方式,分三个节点
1~100 的数据对 3 取余,可以分为三类
- 余数为 0
- 余数为 1
- 余数为 2
那么同样的分 4 个节点就是 hash (key)%4
节点取余的优点是简单,客户端分片直接是哈希 + 取余
一致性哈希
客户端进行分片,哈希 + 顺时针取余
虚拟槽分区
Redis Cluster
采用虚拟槽分区
虚拟槽分区巧妙地使用了哈希空间,使用分散度良好的哈希函数把所有的数据映射到一个固定范围内的整数集合,整数定义为槽(slot)。
Redis Cluster 槽的范围是 0 ~ 16383。
槽是集群内数据管理和迁移的基本单位。采用大范围的槽的主要目的是为了方便数据的拆分和集群的扩展,
每个节点负责一定数量的槽。
搭建 redis cluster
搭建集群分为几部
- 准备节点(几匹马儿)
- 节点通信(几匹马儿分配主从)
- 分配槽位给节点(slot 分配给马儿)
redis-cluster 集群架构
多个服务端,负责读写,彼此通信,redis指定了16384个槽。
多匹马儿,负责运输数据,马儿分配16384个槽位,管理数据。
ruby的脚本自动就把分配槽位这事做了
安装方式
官方提供通过 ruby 语言的脚本一键安装
环境准备
通过配置,开启 redis-cluster
port 7000
daemonize yes
dir "/opt/redis/data"
logfile "7000.log"
dbfilename "dump-7000.rdb"
cluster-enabled yes #开启集群模式
cluster-config-file nodes-7000.conf #集群内部的配置文件
cluster-require-full-coverage no #redis cluster需要16384个slot都正常的时候才能对外提供服务,换句话说,只要任何一个slot异常那么整个cluster不对外提供服务。 因此生产环境一般为no
redis 支持多实例的功能,我们在单机演示集群搭建,需要 6 个实例,三个是主节点,三个是从节点,数量为 6 个节点才能保证高可用的集群。
每个节点仅仅是端口运行的不同!
[root@yugo /opt/redis/config 17:12:30]#ls
redis-7000.conf redis-7002.conf redis-7004.conf
redis-7001.conf redis-7003.conf redis-7005.conf
#确保每个配置文件中的端口修改!!
运行 redis 实例
redis-server redis-7000.conf
redis-server redis-7001.conf
redis-server redis-7002.conf
redis-server redis-7003.conf
redis-server redis-7004.conf
redis-server redis-7005.conf
下载安装 Ruby
准备ruby的编程环境
1.下载ruby的源码包
wget https://cache.ruby-lang.org/pub/ruby/2.3/ruby-2.3.1.tar.gz
2.解压缩ruby远吗
tar -xvf ruby-2.3.1.tar.gz
3.开始编译安装ruby
进入ruby源码包
./configure --prefix=/opt/ruby/
4.开始编译且编译安装
make && make install
5.配置ruby的环境变量
vim /etc/profile
追加写入如下配置
PATH=$PATH:/opt/ruby/bin
source /etc/profile
安装 ruby 操作 redis 的模块
1.下载ruby操作redis的模块雷士python的pip
wget http://rubygems.org/downloads/redis-3.3.0.gem
2.安装
gem install -l redis-3.3.0.gem
3.搜索创建redis集群的命令
find /opt -name redis-trib.rb
一键创建 redis 集群
执行下面一行命令:
/opt/redis-4.0.10/src/redis-trib.rb create --replicas 1 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005
--replicas 进行身份授权
后面的1 代表,每个主节点,只有一个从节点
默认将 7000 7001 70002 设置为主库
将7003 7004 7005 设置为从库
查看集群节点,是否能正常写入数据
redis-cli -p 7000 -c
-p 指定数据库端口
-c 指定开启集群模式
127.0.0.1:7000> set name chao
-> Redirected to slot [5798] located at 127.0.0.1:7001
OK
127.0.0.1:7001> exit
[root@yugo /opt/redis/src 18:46:07]#redis-cli -c -p 7000
127.0.0.1:7000> ping
PONG
127.0.0.1:7000> keys *
(empty list or set)
127.0.0.1:7000> get name
-> Redirected to slot [5798] located at 127.0.0.1:7001
"chao"
docker 入门
docker 简介
Docker 最初是 dotCloud 公司创始人 Solomon Hykes 在法国期间发起的一个公司内部项目,于 2013 年 3 月以 Apache 2.0 授权协议开源,主要项目代码在 GitHub 上进行维护。
Docker 使用 Google 公司推出的 Go 语言 进行开发实现。
docker是linux容器的一种封装,提供简单易用的容器使用接口。它是最流行的Linux容器解决方案。
docker的接口相当简单,用户可以方便的创建、销毁容器。
docker将应用程序与程序的依赖,打包在一个文件里面。运行这个文件就会生成一个虚拟容器。
程序运行在虚拟容器里,如同在真实物理机上运行一样,有了docker,就不用担心环境问题了。
docker 应用场景
web应用的自动化打包和发布
自动化测试和持续集成、发布
在服务型环境中部署和调整数据库或其他应用
docker VS 传统虚拟机
特性 |
容器 |
虚拟机 |
启动 |
秒级 |
分钟级 |
硬盘使用 |
一般为 MB |
一般为 GB |
性能 |
接近原生 |
弱 |
系统支持量 |
单机支持上千个容器 |
一般几十个 |
环境配置的难题
让开发人员最头疼的麻烦事之一就是环境配置了,每台计算机的环境都不相同,应该如何确保自己的程序换一台机器能运行起来呢?
用户必须确保的是:
操作系统的相同
各种平台库和组件的安装
例如python依赖包,环境变量等
如何一些低版本的依赖模块和当前环境不兼容,那就头疼了。。。。。
如果环境配置这么痛苦的话,换一台机器,就得重新配置一下,那么在安装软件的时候,带着原始环境一模一样的复制过来。
虚拟机
虚拟机也可以制作模板,基于模板创建虚拟机,保证环境问题一致
虚拟机(virtual machine)就是带环境安装的一种解决方案。它可以在一种操作系统里面运行另一种操作系统,比如在 Windows 系统里面运行 Linux 系统。应用程序对此毫无感知,因为虚拟机看上去跟真实系统一模一样,而对于底层系统来说,虚拟机就是一个普通文件,不需要了就删掉,对其他部分毫无影响。
虽然用户可以通过虚拟机还原软件的原始环境。但是,这个方案有几个缺点。
(1)资源占用多
虚拟机会独占一部分内存和硬盘空间。它运行的时候,其他程序就不能使用这些资源了。哪怕虚拟机里面的应用程序,真正使用的内存只有 1MB,虚拟机依然需要几百 MB 的内存才能运行。
(2)冗余步骤多
虚拟机是完整的操作系统,一些系统级别的操作步骤,往往无法跳过,比如用户登录。
(3)启动慢
启动操作系统需要多久,启动虚拟机就需要多久。可能要等几分钟,应用程序才能真正运行。
Linux 容器
现在:自从用上docker容器后,可以实现开发、测试和生产环境的统一化和标准化。
镜像作为标准的交付件,可在开发、测试和生产环境上以容器来运行,最终实现三套环境上的应用以及运行所依赖内容的完全一致。
由于虚拟机的诸多问题,Linux发展出了另一种虚拟化技术:Linux容器(Linux Containers,缩写LXC)
Linux容器不是模拟一个完整的操作系统,而是对进程进行隔离。在正常进程的外面套了一个保护层,对于容器里面进程来说,它接触的资源都是虚拟的,从而实现和底层系统的隔离。
(1)启动快
容器里面的应用,直接就是底层系统的一个进程,而不是虚拟机内部的进程。所以,启动容器相当于启动本机的一个进程,而不是启动一个操作系统,速度就快很多。
(2)资源占用少
容器只占用需要的资源,不占用那些没有用到的资源;虚拟机由于是完整的操作系统,不可避免要占用所有资源。另外,多个容器可以共享资源,虚拟机都是独享资源。
(3)体积小
容器只要包含用到的组件即可,而虚拟机是整个操作系统的打包,所以容器文件比虚拟机文件要小很多。
总之,容器有点像轻量级的虚拟机,能够提供虚拟化的环境,但是成本开销小得多。
docker 容器的优势
更高效的利用系统资源
由于容器不需要进行硬件虚拟以及运行完整操作系统等额外开销,Docker 对系统 资源的利用率更高。
无论是应用执行速度、内存损耗或者文件存储速度,都要比传 统虚拟机技术更高效。因此,相比虚拟机技术,一个相同配置的主机,往往可以运 行更多数量的应用。
更快速的启动时间
传统的虚拟机技术启动应用服务往往需要数分钟,而 Docker 容器应用,由于直接 运行于宿主内核,无需启动完整的操作系统,因此可以做到秒级、甚至毫秒级的启 动时间。大大的节约了开发、测试、部署的时间。
一致的运行环境
开发过程中一个常见的问题是环境一致性问题。由于开发环境、测试环境、生产环 境不一致,导致有些 bug 并未在开发过程中被发现。
而 Docker 的镜像提供了除内 核外完整的运行时环境,确保了应用运行环境一致性,从而不会再出现 “这段代码 在我机器上没问题啊” 这类问题。
持续交付和部署
对开发和运维(DevOps)人员来说,最希望的就是一次创建或配置,可以在任意 地方正常运行。
使用 Docker 可以通过定制应用镜像来实现持续集成、持续交付、部署。开发人员 可以通过 Dockerfile 来进行镜像构建,并结合 持续集成(Continuous Integration) 系 统进行集成测试,
而运维人员则可以直接在生产环境中快速部署该镜像,甚至结合 持续部署(Continuous Delivery/Deployment) 系统进行自动部署。
而且使用 Dockerfile 使镜像构建透明化,不仅仅开发团队可以理解应用运行环 境,也方便运维团队理解应用运行所需条件,帮助更好的生产环境中部署该镜像。
更轻松的迁移
由于 Docker 确保了执行环境的一致性,使得应用的迁移更加容易。Docker 可以在 很多平台上运行,无论是物理机、虚拟机、公有云、私有云,甚至是笔记本,其运 行结果是一致的。
因此用户可以很轻易的将在一个平台上运行的应用,迁移到另一 个平台上,而不用担心运行环境的变化导致应用无法正常运行的情况。
工作中的虚拟化和容器
docker 三大概念
容器三大基本概念
镜像 image
容器 container
仓库 repository
docker镜像
Docker镜像就是一个只读的模板。
例如:一个镜像可以包含一个完整的CentOS操作系统环境,里面仅安装了Apache或用户需要的其他应用程序。
镜像可以用来创建Docker容器。
Docker提供了一个很简单的机制来创建镜像或者更新现有的镜像,用户甚至可以直接从其他人那里下载一个已经做好的镜像来直接使用。
image的分层存储
因为镜像包含完整的root文件系统,体积是非常庞大的,因此docker在设计时按照Union FS的技术,将其设计为分层存储的架构。
镜像不是ISO那种完整的打包文件,镜像只是一个虚拟的概念,他不是一个完整的文件,而是由一组文件组成,或者多组文件系统联合组成。
docker容器(container)
image和container的关系,就像面向对象程序设计中的 类和实例一样,镜像是静态的定义(class),容器是镜像运行时的实体(object)。
容器可以被创建、启动、停止、删除、暂停
Docker利用容器来运行应用。
容器是从镜像创建的运行实例。它可以被启动、开始、停止、删除。每个容器都是相互隔离的,保证安全的平台。
可以把容器看做是一个简易版的Linux环境(包括root用户权限、进程空间、用户空间和网络空间等)和运行在其中的应用程序。
注意:镜像是只读的,容器在启动的时候创建一层可写层作为最上层。
docker仓库(repository)
仓库是集中存放镜像文件的场所。有时候把仓库和仓库注册服务器(Registry)混为一谈,并不严格区分。实际上,仓库注册服务器上往往存放着多个仓库,每个仓库中又包含了多个镜像,每个镜像有不同的标签(tag)。
仓库分为公开仓库(Public)和私有仓库(Private)两种形式。
最大的公开仓库是Docker Hub,存放了数量庞大的镜像供用户下载。国内的公开仓库包括Docker Pool等,可以提供大陆用户更稳定快读的访问。
当用户创建了自己的镜像之后就可以使用push命令将它上传到公有或者私有仓库,这样下载在另外一台机器上使用这个镜像时候,只需需要从仓库上pull下来就可以了。
注意:Docker仓库的概念跟Git类似,注册服务器可以理解为GitHub这样的托管服务。
docker Registry
Docker Registry 公开服务是开放给用户使用、允许用户管理镜像的 Registry 服 务。一般这类公开服务允许用户免费上传、下载公开的镜像,并可能提供收费服务 供用户管理私有镜像。
最常使用的 Registry 公开服务是官方的 Docker Hub,这也是默认的 Registry,并 拥有大量的高质量的官方镜像。
除此以外,还有 CoreOS 的 Quay.io,CoreOS 相 关的镜像存储在这里;Google 的 Google Container Registry,Kubernetes 的镜像 使用的就是这个服务。
由于某些原因,在国内访问这些服务可能会比较慢。
国内的一些云服务商提供了针 对 Docker Hub 的镜像服务(Registry Mirror),这些镜像服务被称为加速器。常见 的有 阿里云加速器、DaoCloud 加速器、灵雀云加速器等。
使用加速器会直接从国内的地址下载 Docker Hub 的镜像,比直接从官方网站下载速度会提高很多。在后 面的章节中会有进一步如何配置加速器的讲解。
国内也有一些云服务商提供类似于 Docker Hub 的公开服务。比如 时速云镜像仓 库、网易云镜像服务、DaoCloud 镜像市场、阿里云镜像库等。
CentOS 安装 docker
官方教程如下
https://docs.docker.com/install/linux/docker-ce/centos/#upgrade-docker-after-using-the-convenience-script
1.卸载旧版本
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-selinux \
docker-engine-selinux \
docker-engine
2.设置存储库
sudo yum install -y yum-utils \
device-mapper-persistent-data \
lvm2
sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
3.安装docker社区版
sudo yum install docker-ce
4.启动关闭docker
systemctl start docker
docker 版本
Docker 是一个开源的商业产品,有两个版本:社区版(Community Edition,缩写为 CE)和企业版(Enterprise Edition,缩写为 EE)。
企业版包含了一些收费服务,个人开发者一般用不到。本文的介绍都针对社区版。
系统环境准备
docker最低支持centos7且在64位平台上,内核版本在3.10以上
[root@oldboy_python ~ 10:48:11]#uname -r
3.10.0-693.el7.x86_64
Docker 镜像加速器
https://www.daocloud.io/mirror#accelerator-doc
https://www.cnblogs.com/pyyu/p/6925606.html
#一条命令加速
curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://95822026.m.daocloud.io
好像有一个坑,请修改配置文件 /etc/docker/daemon.json
改成如下配置即可
{"registry-mirrors": ["http://f1361db2.m.daocloud.io"]}
3.重启docker
systemctl restart docker
yum 安装
阿里云默认也有docker软件,也可以下载,只是版本较低
正在安装:
docker x86_64 2:1.13.1-88.git07f3374.el7.centos extras 17 M
3.安装docker
yum install docker
检测是否安装完毕
rpm -qi docker
4.启动docker
systemctl start/status docker
5.确认docker以及启动
docker version
docker 基础命令注释


[root@docker ~]# docker --help
Usage:
docker [OPTIONS] COMMAND [arg...]
docker daemon [ --help | ... ]
docker [ --help | -v | --version ]
A
self-sufficient runtime for containers.
Options:
--config=~/.docker Location of client config files #客户端配置文件的位置
-D, --debug=false Enable debug mode #启用Debug调试模式
-H, --host=[] Daemon socket(s) to connect to #守护进程的套接字(Socket)连接
-h, --help=false Print usage #打印使用
-l, --log-level=info Set the logging level #设置日志级别
--tls=false Use TLS; implied by--tlsverify #
--tlscacert=~/.docker/ca.pem Trust certs signed only by this CA #信任证书签名CA
--tlscert=~/.docker/cert.pem Path to TLS certificate file #TLS证书文件路径
--tlskey=~/.docker/key.pem Path to TLS key file #TLS密钥文件路径
--tlsverify=false Use TLS and verify the remote #使用TLS验证远程
-v, --version=false Print version information and quit #打印版本信息并退出
Commands:
attach Attach to a running container #当前shell下attach连接指定运行镜像
build Build an image from a Dockerfile #通过Dockerfile定制镜像
commit Create a new image from a container''s changes #提交当前容器为新的镜像
cp Copy files/folders from a container to a HOSTDIR or to STDOUT #从容器中拷贝指定文件或者目录到宿主机中
create Create a new container #创建一个新的容器,同run 但不启动容器
diff Inspect changes on a container''s filesystem #查看docker容器变化
events Get real time events from the server#从docker服务获取容器实时事件
exec Run a command in a running container#在已存在的容器上运行命令
export Export a container''s filesystem as a tar archive #导出容器的内容流作为一个tar归档文件(对应import)
history Show the history of an image #展示一个镜像形成历史
images List images #列出系统当前镜像
import Import the contents from a tarball to create a filesystem image #从tar包中的内容创建一个新的文件系统映像(对应export)
info Display system-wide information #显示系统相关信息
inspect Return low-level information on a container or image #查看容器详细信息
kill Kill a running container #kill指定docker容器
load Load an image from a tar archive or STDIN #从一个tar包中加载一个镜像(对应save)
login Register or log in to a Docker registry#注册或者登陆一个docker源服务器
logout Log out from a Docker registry #从当前Docker registry退出
logs Fetch the logs of a container #输出当前容器日志信息
pause Pause all processes within a container#暂停容器
port List port mappings or a specific mapping for the CONTAINER #查看映射端口对应的容器内部源端口
ps List containers #列出容器列表
pull Pull an image or a repository from a registry #从docker镜像源服务器拉取指定镜像或者库镜像
push Push an image or a repository to a registry #推送指定镜像或者库镜像至docker源服务器
rename Rename a container #重命名容器
restart Restart a running container #重启运行的容器
rm Remove one or more containers #移除一个或者多个容器
rmi Remove one or more images #移除一个或多个镜像(无容器使用该镜像才可以删除,否则需要删除相关容器才可以继续或者-f强制删除)
run Run a command in a new container #创建一个新的容器并运行一个命令
save Save an image(s) to a tar archive#保存一个镜像为一个tar包(对应load)
search Search the Docker Hub for images #在docker
hub中搜索镜像
start Start one or more stopped containers#启动容器
stats Display a live stream of container(s) resource usage statistics #统计容器使用资源
stop Stop a running container #停止容器
tag Tag an image into a repository #给源中镜像打标签
top Display the running processes of a container #查看容器中运行的进程信息
unpause Unpause all processes within a container #取消暂停容器
version Show the Docker version information#查看容器版本号
wait Block until a container stops, then print its exit code #截取容器停止时的退出状态值
Run ''docker COMMAND --help'' for more information on a command. #运行docker命令在帮助可以获取更多信息
使用 docker 镜像
从仓库获取镜像 管理本地主机的镜像
获取镜像
从docker registry获取镜像的命令是docker pull。命令格式是:
docker pull [选项][docker registry地址] 仓库名:标签
docker register地址:地址的格式一般是 域名:端口,默认地址是docker hub
仓库名:仓库名是两段格式,用户名/软件名,如果不写用户,默认docker hub用户名是library,也就是官方镜像
镜像文件
docker是把应用程序和其依赖打包在image文件里面,只有通过这个镜像文件才能生成docker容器。
一个image文件可以生成多个容器实例。
列出服务器所有镜像文件
#列出所有的image文件
docker image ls
#删除image文件
docker image rm [imagename]
搜索 docker 镜像
[root@docker ~]# docker search centos #搜索所有centos的docker镜像
INDEX NAME(名称) DESCRIPTION(描述) STARS(下载次数)OFFICIAL(官方) AUTOMATED(自动化)
docker.io docker.io/centos The official build of CentOS. 1781 [OK]
docker.io docker.io/jdeathe/centos-ssh CentOS-6 6.7 x86_64 / 14 [OK]
……
获取 docker 镜像
可以使用docker pull命令来从仓库获取所需要的镜像。下面的例子将从Docker Hub仓库下载一个Centos操作系统的镜像。
[root@docker ~]# docker pull centos #获取centos镜像
[root@docker ~]# docker run -it centos /bin/bash #完成后可以使用该镜像创建一个容器
查看 docker 镜像
镜像的ID唯一标识了镜像,如果ID相同,说明是同一镜像。
TAG信息来区分不同发行版本,如果不指定具体标记,默认使用latest标记信息。
[root@docker ~]# docker images #查看docker镜像
REPOSITORY(来自那个仓库) TAG(标签) IMAGE ID(唯一ID) CREATED(创建时间) VIRTUAL SIZE(大小)
docker.io/centos latest 60e65a8e4030 5
days ago 196.6 MB
docker.io/nginx latest 813e3731b203 13
days ago 133.8 MB
删除 Docker 镜像
如果要移除本地的镜像,可以使用docker rmi命令(在删除镜像之前先用docker rm删除依赖于这个镜像的所有容器)。注意docker rm 命令是移除容器。
[root@docker ~]# docker rmi imageID #删除docker镜像
运行镜像,且产生一个容器记录,且进入容器空间内
docker run -it centos /bin/bash
-it 交互式的终端,代表我可以在容器中输入命令
/bin/bash 指定shell解释器
创建一个容器,在容器安装一个 vim 工具
docker run -it centos /bin/bash
#在容器空间内装vim
yum install vim -y
#使用vim
docker run -it 容器di /bin/bash
vim
容器由于没有后台任务,立即挂掉,但是我们可以提交这个容器为新的镜像
exit
docker commit a3bd9bca8c80 shenzhenqishi1qi/centos-vim
#查看已提交的镜像记录
docker images
基于这个拥有 vim 的镜像,创建新的容器
docker run -it 镜像id /bin/bash
导出 docker 镜像
如果要导出镜像到本地文件,可以使用docker save命令。
[root@docker ~]#
#exit 先退出 docker
docker save shenzhenqishi1qi/centos-vim > /opt/centos-vim.tar.gz
导入 docker 镜像
可以使用docker load从本地文件中导入到本地docker镜像库
[root@docker ~]# docker load < /opt/centos-vim.tar.gz #导入本地镜像到docker镜像库
[root@docker~]# docker images #查看镜像导入情况
启动 docker 容器的方式
1.基于镜像创建新的容器
2.对于已运行的容器,进行启停
docker stop 容器id
docker start 容器id
#这条命令意思是:创建一个只运行一次的容器
docker run centos /bin/echo "hehe"
运行一个容器记录,且给与名字
docker run --name mydocker -it centos /bin/bash#启动一个bash终端,允许用户进行交互
--name:给容器定义一个名称
-i:则让容器的标准输入保持打开。
-t:让Docker分配一个伪终端,并绑定到容器的标准输入上
/bin/bash:执行一个命令
docker 与 "hello docker"
hello world是程序员启蒙语言,我们通过最简单的image文件“hello-world”,来感受一下docker。
#获取镜像 hello-world
docker pull hello-world
#检查镜像
docker images
#运行image文件,可以用容器id
docker run hello-world
#检查docker容器进程
docker ps
#检查所有运行过的容器
docker ps -a
运行一个 ubuntu 容器
1.查看系统的版本信息
cat /etc/redhat-release #这个命令查看红帽系列的系统
cat /etc/os-release
2.运行一个ubuntu容器
docker run -it ubuntu /bin/bash
删除容器记录
docker rm 容器id
docker -aq #列出所有容器记录的id
docker stop `docker ps -aq` #停止所有正在运行的容器
docker rm `docker ps -aq` #一次性删除所有容器记录
docker rmi `docker images -aq` #一次性删除所有本地的镜像记录
暴露容器端口,端口映射
-P 参数会随机映射端口到容器开放的网络端口
docker run -d -P training/webapp python app.py
-d 后台运行
-P 端口映射, 随机映射 ,物理机的随机端口:容器内暴露的端口
如果本地没有镜像文件,docker run会自动帮我们下载镜像
在docker run centos
[root@qishione ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e3e0be2b22a8 training/webapp "python app.py" 2 seconds ago Up 1 second 0.0.0.0:32769->5000/tcp qishiweb
只要我访问宿主机的32769端口也就是访问到了容器内的5000端口
重启后容器端口号会随机改变
[root@yidashi opt]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
054fda5751a3 training/webapp "python app.py" About a minute ago Up About a minute 0.0.0.0:32768->5000/tcp kind_euclid
[root@yidashi opt]# netstat -tunlp |grep 32768
tcp6 0 0 :::32768 :::* LISTEN 98765/docker-proxy-
[root@yidashi opt]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
054fda5751a3 training/webapp "python app.py" 5 minutes ago Up 5 minutes 0.0.0.0:32768->5000/tcp kind_euclid
[root@yidashi opt]# docker stop 054
054
[root@yidashi opt]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@yidashi opt]# docker start 054
054
##从原来的32768变成32769了
[root@yidashi opt]# docker port 054
5000/tcp -> 0.0.0.0:32769
指定端口映射,启动容器应用
docker run -d -p 9999:5000 --name my9999webapp training/webapp python app.py
不间断打印容器的日志信息
docker logs -f 容器id
利用 dockerfile 定制镜像
镜像是容器的基础,每次执行 docker run 的时候都会指定哪个镜像作为容器运行的基础。我们之前的例子都是使用来自 docker hub 的镜像,直接使用这些镜像只能满足一定的需求,当镜像无法满足我们的需求时,就得自定制这些镜像。
镜像的定制就是定制每一层所添加的配置、文件。如果可以吧每一层修改、安装、构建、操作的命令都写入到一个脚本,用脚本来构建、定制镜像,这个脚本就是 dockerfile。
Dockerfile 是一个文本文件,其内包含了一条条的指令 (Instruction),每一条指令 构建一层,因此每一条指令的内容,就是描述该层应当如何构建。
FROM scratch #制作base image 基础镜像,尽量使用官方的image作为base image
FROM centos #使用base image
FROM ubuntu:14.04 #带有tag的base image
LABEL version=“1.0” #容器元信息,帮助信息,Metadata,类似于代码注释
LABEL maintainer=“yc_uuu@163.com"
#对于复杂的RUN命令,避免无用的分层,多条命令用反斜线换行,合成一条命令!
RUN yum update && yum install -y vim \
Python-dev #反斜线换行
RUN /bin/bash -c "source $HOME/.bashrc;echo $HOME”
WORKDIR /root #相当于linux的cd命令,改变目录,尽量使用绝对路径!!!不要用RUN cd
WORKDIR /test #如果没有就自动创建
WORKDIR demo #再进入demo文件夹
RUN pwd #打印结果应该是/test/demo
ADD and COPY
ADD hello / #把本地文件添加到镜像中,吧本地的hello可执行文件拷贝到镜像的/目录
ADD test.tar.gz / #添加到根目录并解压
WORKDIR /root
ADD hello test/ #进入/root/ 添加hello可执行命令到test目录下,也就是/root/test/hello 一个绝对路径
COPY hello test/ #等同于上述ADD效果
ADD与COPY
- 优先使用COPY命令
-ADD除了COPY功能还有解压功能
添加远程文件/目录使用curl或wget
ENV #环境变量,尽可能使用ENV增加可维护性
ENV MYSQL_VERSION 5.6 #设置一个mysql常量
RUN yum install -y mysql-server=“${MYSQL_VERSION}”
------这里需要稍微理解一下了-------中级知识---先不讲
VOLUME and EXPOSE
存储和网络
RUN and CMD and ENTRYPOINT
RUN:执行命令并创建新的Image Layer
CMD:设置容器启动后默认执行的命令和参数
ENTRYPOINT:设置容器启动时运行的命令
Shell格式和Exec格式
RUN yum install -y vim
CMD echo ”hello docker”
ENTRYPOINT echo “hello docker”
Exec格式
RUN [“apt-get”,”install”,”-y”,”vim”]
CMD [“/bin/echo”,”hello docker”]
ENTRYPOINT [“/bin/echo”,”hello docker”]
通过shell格式去运行命令,会读取$name指令,而exec格式是仅仅的执行一个命令,而不是shell指令
cat Dockerfile
FROM centos
ENV name Docker
ENTRYPOINT [“/bin/echo”,”hello $name”]#这个仅仅是执行echo命令,读取不了shell变量
ENTRYPOINT [“/bin/bash”,”-c”,”echo hello $name"]
CMD
容器启动时默认执行的命令
如果docker run指定了其他命令(docker run -it [image] /bin/bash ),CMD命令被忽略
如果定义多个CMD,只有最后一个执行
ENTRYPOINT
让容器以应用程序或服务形式运行
不会被忽略,一定会执行
最佳实践:写一个shell脚本作为entrypoint
COPY docker-entrypoint.sh /usr/local/bin
ENTRYPOINT [“docker-entrypoint.sh]
EXPOSE 27017
CMD [“mongod”]
[root@master home]# more Dockerfile
FROm centos
ENV name Docker
#CMD ["/bin/bash","-c","echo hello $name"]
ENTRYPOINT ["/bin/bash","-c","echo hello $name”]
发布 docker image 到仓库
1.docker 提供了一个类似于 github 的仓库 dockerhub,
网址 https://hub.docker.com/ 需要注册使用
2. 注册 docker id 后,在 linux 中登录 dockerhub
docker login
注意要保证 image 的 tag 是账户名,如果镜像名字不对,需要改一下 tag
docker tag chaoyu/centos-vim yuchao163/centos-vim
语法是: docker tag 仓库名 yuchao163 / 仓库名
3. 推送 docker image 到 dockerhub
docker push yuchao163/centps-cmd-exec:latest
4. 在 dockerhub 中检查镜像
https://hub.docker.com/
5. 删除本地镜像,测试下载 pull 镜像文件
docker pull yuchao163/centos-entrypoint-exec
私有仓库
1.官方提供的私有仓库docker registry用法
https://yeasy.gitbooks.io/docker_practice/repository/registry.html
2.一条命令下载registry镜像并且启动私有仓库容器
私有仓库会被创建在容器的/var/lib/registry下,因此通过-v参数将镜像文件存储到本地的/opt/data/registry下
端口映射容器中的5000端口到宿主机的5000端口
docker run -d -p 5000:5000-v /opt/data/registry:/var/lib/registry registry
#-d 后台运行
#-p 端口映射 宿主机的5000:容器内的5000
#-v 数据卷挂载 宿主机的 /opt/data/registry :/var/lib/registry
#registry 镜像名
3.检查启动的registry容器
docker ps
4.测试连接容器
telnet 192.168.119.10 5000
5.修改镜像tag,以docker registry的地址端口开头
docker tag hello-world:latest 192.168.119.10:5000/hello-world:latest
6.查看docker镜像,找到registry的镜像
docker images
7.Docker 默认不允许非 HTTPS 方式推送镜像。我们可以通过 Docker 的配置选项来取消这个限制,这里必须写正确json数据
[root@master /]# cat /etc/docker/daemon.json
{"registry-mirrors": ["http://95822026.m.daocloud.io"],
"insecure-registries":["192.168.119.10:5000"]
}
写入到docker服务中,写入到[Service]配置块中,加载此配置文件
[root@master home]# grep ''EnvironmentFile=/etc/docker/daemon.json'' /lib/systemd/system/docker.service
EnvironmentFile=-/etc/docker/daemon.json
8.修改了docker配置文件,重新加载docker
systemctl daemon-reload
9.重启docker
systemctl restart docker
10.重启了docker,刚才的registry容器进程挂掉了,因此重新启动它
docker ps -a
docker start 容器id
11.推送本地镜像
docker push 192.168.119.10:5000/hello-world
12.由于docker registry没有web节目,但是提供了API数据
官网教程:https://docs.docker.com/registry/spec/api/#listing-repositories
curl http://192.168.119.10:5000/v2/_catalog
或者浏览器访问http://192.168.119.10:5000/v2/_catalog
13.删除本地镜像,从私有仓库中下载
docker pull 192.168.119.10:5000/hello-world
打包 flask 程序与 dockerfile
1.在宿主机中,编写一个flask代码文件,和Dockerfile
cd /opt/dockertest/
touch flasktest.py
from flask import Flask
app=Flask(__name__)
@app.route(''/'')
def hello():
return "i love china"
if __name__=="__main__":
app.run(host=''0.0.0.0'',port=8080)
2.构建Dockerfile(必须首字母大写)
1.指引一个基础的系统镜像centos
2.定义作者标签
3.解决环境依赖关系,安装python-setuptools
4.安装flask模块 easy_install flask
5.准备代码文件到容器中 COPY flasktest.py /opt/
6.切换到/opt目录下 workdir /opt
7.暴露容器端口
8.运行代码 python flasktest.py
3.Dockerfile内容如下
[root@qishione dockertest]# cat Dockerfile
FROM centos
LABEL maintainer="深圳骑士1期"
RUN yum install python-setuptools -y
RUN easy_install flask
COPY flasktest.py /opt/
WORKDIR /opt
EXPOSE 8080
CMD ["python","flasktest.py"]
4.构建镜像文件,找到当前目录的Dockerfile,开始构建
docker build -t qishi1qi/flask-web .
-t 打个标记号
5.基于这个镜像,生成容器实例
docker run -d -p 7777:8080 945
6.推送这个镜像到私有仓库
docker tag qishi1qi/flask-web 192.168.11.37:5000/qishi1qi-flaskweb
docker push 192.168.11.37:5000/qishi1qi-flaskweb
容器是运行应用程序的,所以必须得先有一个操作系统为基础
容器是运行应用程序的,所以必须得先有一个操作系统为基础
容器是运行应用程序的,所以必须得先有一个操作系统为基础
docker 容器必须有后台进程在运行,如果 docker 容器内没有任务在运行中,容器就退出
docker 容器必须有后台进程在运行,如果 docker 容器内没有任务在运行中,容器就退出
docker 容器必须有后台进程在运行,如果 docker 容器内没有任务在运行中,容器就退出
(六) Docker 部署 Redis 高可用集群 (sentinel 哨兵模式)
参考并感谢
- 官方文档 https://hub.docker.com/_/redis
- GitHub https://github.com/antirez/redis
- happyJared https://blog.csdn.net/qq_28804275/article/details/80938659
下载 redis 镜像 (不带 tag 标签则表示下载 latest 版本)
docker pull redis
从 github 下载最新的 redis.conf, 注意重要参数
# 端口 port 6379 # 密码 requirepass Mypwd@123456 # 支持数据持久化 appendonly yes # 关闭守护进程 daemonize no # 默认多少个数据库 databases 16 # 从库时需要增加主库配置 # 主库密码(一个集群密码需要保持一致) masterauth Mypwd@123456 # 主库地址和端口 slaveof 172.17.0.1 6379
启动 redis6379 主库
docker run -d \ -p 6379:6379 \ --name redis6379 \ --mount type=bind,source=/var/docker/configs/redis/6379/redis.conf,target=/usr/local/etc/redis/redis.conf \ --mount type=bind,source=/var/docker/datas/redis/6379,target=/data \ --restart always \ redis:latest \ redis-server /usr/local/etc/redis/redis.conf
启动 redis6380 从库 (需要修改 redis.conf 的 port 和从服务器相关配置)
docker run -d \ -p 6380:6380 \ --name redis6380 \ --mount type=bind,source=/var/docker/configs/redis/6380/redis.conf,target=/usr/local/etc/redis/redis.conf \ --mount type=bind,source=/var/docker/datas/redis/6380,target=/data \ --restart always \ redis:latest \ redis-server /usr/local/etc/redis/redis.conf
启动 redis6381 从库 (需要修改 redis.conf 的 port 和从服务器相关配置)
docker run -d \ -p 6381:6381 \ --name redis6381 \ --mount type=bind,source=/var/docker/configs/redis/6381/redis.conf,target=/usr/local/etc/redis/redis.conf \ --mount type=bind,source=/var/docker/datas/redis/6381,target=/data \ --restart always \ redis:latest \ redis-server /usr/local/etc/redis/redis.conf
从 github 下载最新的 sentinel.conf, 注意重要参数
# 端口 port 26379 # 关闭守护进程 daemonize no # 设定监听的redis集群的名称(mymaster)+IP+主库端口+最少从库数量 sentinel monitor mymaster 172.17.0.1 6379 2 # 设定监听的redis集群的密码(集群中主库和从库密码需要保持一致) sentinel auth-pass mymaster Mypwd@123456
开放 redis 和 sentinel 端口并立即生效
firewall-cmd --zone=public --add-port=6379/tcp --permanent firewall-cmd --zone=public --add-port=6380/tcp --permanent firewall-cmd --zone=public --add-port=6381/tcp --permanent firewall-cmd --zone=public --add-port=26379/tcp --permanent firewall-cmd --zone=public --add-port=26380/tcp --permanent firewall-cmd --zone=public --add-port=26381/tcp --permanent firewall-cmd --reload
不修改 redis.conf, 通过命令方式使从库加入集群
docker exec -it redis6380 bash redis-cli -a Mypwd@123456 -p 6380 slaveof 172.17.0.1 6379 config set masterauth Mypwd@123456
docker exec -it redis6381 bash redis-cli -a Mypwd@123456 -p 6381 slaveof 172.17.0.1 6379 config set masterauth Mypwd@123456
主容器查询集群状态
docker exec -it redis6379 bash redis-cli -a Mypwd@123456 -p 6379 info Replication
查看哨兵监控情况 (不同的哨兵登录不同的容器使用客户端 26379 26380 26381)
redis-cli -p 26379 # 查看集群主库情况 sentinel master mymaster # 查看集群从库情况 sentinel slaves mymaster
从库退出集群并保持原先数据 (通过 bash 登录从库容器后,使用 redis-cli 客户端)
slaveof no one
验证哨兵模式 + 集群是否高可用 (通过 bash 登录从库容器后,使用 redis-cli 客户端)
redis-cli -a Mypwd@123456 -p 6379 DEBUG sleep 60
PS: 启动容器之前,需要创建好对应的宿主机的文件目录,宿主机缺少文件会导致容器启动失败
《(六) Docker 部署 Redis 高可用集群 (sentinel 哨兵模式)》CSDN 地址:https://blog.csdn.net/madmarszff/article/details/100902662
《(六) Docker 部署 Redis 高可用集群 (sentinel 哨兵模式)》博客园地址:https://www.cnblogs.com/godzff/p/11530290.html
《(六) Docker 部署 Redis 高可用集群 (sentinel 哨兵模式)》简书地址:
11.Redis 哨兵集群实现高可用
作者:中华石杉
Redis 哨兵集群实现高可用
哨兵的介绍
sentinel,中文名是哨兵。哨兵是 redis 集群机构中非常重要的一个组件,主要有以下功能:
- 集群监控:负责监控 redis master 和 slave 进程是否正常工作。
- 消息通知:如果某个 redis 实例有故障,那么哨兵负责发送消息作为报警通知给管理员。
- 故障转移:如果 master node 挂掉了,会自动转移到 slave node 上。
- 配置中心:如果故障转移发生了,通知 client 客户端新的 master 地址。
哨兵用于实现 redis 集群的高可用,本身也是分布式的,作为一个哨兵集群去运行,互相协同工作。
- 故障转移时,判断一个 master node 是否宕机了,需要大部分的哨兵都同意才行,涉及到了分布式选举的问题。
- 即使部分哨兵节点挂掉了,哨兵集群还是能正常工作的,因为如果一个作为高可用机制重要组成部分的故障转移系统本身是单点的,那就很坑爹了。
哨兵的核心知识
- 哨兵至少需要 3 个实例,来保证自己的健壮性。
- 哨兵 + redis 主从的部署架构,是不保证数据零丢失的,只能保证 redis 集群的高可用性。
- 对于哨兵 + redis 主从这种复杂的部署架构,尽量在测试环境和生产环境,都进行充足的测试和演练。
哨兵集群必须部署 2 个以上节点,如果哨兵集群仅仅部署了 2 个哨兵实例,quorum = 1。
+----+ +----+
| M1 |---------| R1 |
| S1 | | S2 |
+----+ +----+
配置 quorum=1
,如果 master 宕机, s1 和 s2 中只要有 1 个哨兵认为 master 宕机了,就可以进行切换,同时 s1 和 s2 会选举出一个哨兵来执行故障转移。但是同时这个时候,需要 majority,也就是大多数哨兵都是运行的。
2 个哨兵,majority=2
3 个哨兵,majority=2
4 个哨兵,majority=2
5 个哨兵,majority=3
...
如果此时仅仅是 M1 进程宕机了,哨兵 s1 正常运行,那么故障转移是 OK 的。但是如果是整个 M1 和 S1 运行的机器宕机了,那么哨兵只有 1 个,此时就没有 majority 来允许执行故障转移,虽然另外一台机器上还有一个 R1,但是故障转移不会执行。
经典的 3 节点哨兵集群是这样的:
+----+
| M1 |
| S1 |
+----+
|
+----+ | +----+
| R2 |----+----| R3 |
| S2 | | S3 |
+----+ +----+
配置 quorum=2
,如果 M1 所在机器宕机了,那么三个哨兵还剩下 2 个,S2 和 S3 可以一致认为 master 宕机了,然后选举出一个来执行故障转移,同时 3 个哨兵的 majority 是 2,所以还剩下的 2 个哨兵运行着,就可以允许执行故障转移。
redis 哨兵主备切换的数据丢失问题
两种情况和导致数据丢失
主备切换的过程,可能会导致数据丢失:
- 异步复制导致的数据丢失
因为 master->slave 的复制是异步的,所以可能有部分数据还没复制到 slave,master 就宕机了,此时这部分数据就丢失了。
- 脑裂导致的数据丢失
脑裂,也就是说,某个 master 所在机器突然脱离了正常的网络,跟其他 slave 机器不能连接,但是实际上 master 还运行着。此时哨兵可能就会认为 master 宕机了,然后开启选举,将其他 slave 切换成了 master。这个时候,集群里就会有两个 master ,也就是所谓的脑裂。
此时虽然某个 slave 被切换成了 master,但是可能 client 还没来得及切换到新的 master,还继续向旧 master 写数据。因此旧 master 再次恢复的时候,会被作为一个 slave 挂到新的 master 上去,自己的数据会清空,重新从新的 master 复制数据。而新的 master 并没有后来 client 写入的数据,因此,这部分数据也就丢失了。
数据丢失问题的解决方案
进行如下配置:
min-slaves-to-write 1
min-slaves-max-lag 10
表示,要求至少有 1 个 slave,数据复制和同步的延迟不能超过 10 秒。
如果说一旦所有的 slave,数据复制和同步的延迟都超过了 10 秒钟,那么这个时候,master 就不会再接收任何请求了。
- 减少异步复制数据的丢失
有了 min-slaves-max-lag
这个配置,就可以确保说,一旦 slave 复制数据和 ack 延时太长,就认为可能 master 宕机后损失的数据太多了,那么就拒绝写请求,这样可以把 master 宕机时由于部分数据未同步到 slave 导致的数据丢失降低的可控范围内。
- 减少脑裂的数据丢失
如果一个 master 出现了脑裂,跟其他 slave 丢了连接,那么上面两个配置可以确保说,如果不能继续给指定数量的 slave 发送数据,而且 slave 超过 10 秒没有给自己 ack 消息,那么就直接拒绝客户端的写请求。因此在脑裂场景下,最多就丢失 10 秒的数据。
sdown 和 odown 转换机制
- sdown 是主观宕机,就一个哨兵如果自己觉得一个 master 宕机了,那么就是主观宕机
- odown 是客观宕机,如果 quorum 数量的哨兵都觉得一个 master 宕机了,那么就是客观宕机
sdown 达成的条件很简单,如果一个哨兵 ping 一个 master,超过了 is-master-down-after-milliseconds
指定的毫秒数之后,就主观认为 master 宕机了;如果一个哨兵在指定时间内,收到了 quorum 数量的其它哨兵也认为那个 master 是 sdown 的,那么就认为是 odown 了。
哨兵集群的自动发现机制
哨兵互相之间的发现,是通过 redis 的 pub/sub
系统实现的,每个哨兵都会往 __sentinel__:hello
这个 channel 里发送一个消息,这时候所有其他哨兵都可以消费到这个消息,并感知到其他的哨兵的存在。
每隔两秒钟,每个哨兵都会往自己监控的某个 master+slaves 对应的 __sentinel__:hello
channel 里发送一个消息,内容是自己的 host、ip 和 runid 还有对这个 master 的监控配置。
每个哨兵也会去监听自己监控的每个 master+slaves 对应的 __sentinel__:hello
channel,然后去感知到同样在监听这个 master+slaves 的其他哨兵的存在。
每个哨兵还会跟其他哨兵交换对 master
的监控配置,互相进行监控配置的同步。
slave 配置的自动纠正
哨兵会负责自动纠正 slave 的一些配置,比如 slave 如果要成为潜在的 master 候选人,哨兵会确保 slave 复制现有 master 的数据;如果 slave 连接到了一个错误的 master 上,比如故障转移之后,那么哨兵会确保它们连接到正确的 master 上。
slave->master 选举算法
如果一个 master 被认为 odown 了,而且 majority 数量的哨兵都允许主备切换,那么某个哨兵就会执行主备切换操作,此时首先要选举一个 slave 来,会考虑 slave 的一些信息:
- 跟 master 断开连接的时长
- slave 优先级
- 复制 offset
- run id
如果一个 slave 跟 master 断开连接的时间已经超过了 down-after-milliseconds
的 10 倍,外加 master 宕机的时长,那么 slave 就被认为不适合选举为 master。
(down-after-milliseconds * 10) + milliseconds_since_master_is_in_SDOWN_state
接下来会对 slave 进行排序:
- 按照 slave 优先级进行排序,slave priority 越低,优先级就越高。
- 如果 slave priority 相同,那么看 replica offset,哪个 slave 复制了越多的数据,offset 越靠后,优先级就越高。
- 如果上面两个条件都相同,那么选择一个 run id 比较小的那个 slave。
quorum 和 majority
每次一个哨兵要做主备切换,首先需要 quorum 数量的哨兵认为 odown,然后选举出一个哨兵来做切换,这个哨兵还需要得到 majority 哨兵的授权,才能正式执行切换。
如果 quorum < majority,比如 5 个哨兵,majority 就是 3,quorum 设置为 2,那么就 3 个哨兵授权就可以执行切换。
但是如果 quorum >= majority,那么必须 quorum 数量的哨兵都授权,比如 5 个哨兵,quorum 是 5,那么必须 5 个哨兵都同意授权,才能执行切换。
configuration epoch
哨兵会对一套 redis master+slaves 进行监控,有相应的监控的配置。
执行切换的那个哨兵,会从要切换到的新 master(salve->master)那里得到一个 configuration epoch,这就是一个 version 号,每次切换的 version 号都必须是唯一的。
如果第一个选举出的哨兵切换失败了,那么其他哨兵,会等待 failover-timeout 时间,然后接替继续执行切换,此时会重新获取一个新的 configuration epoch,作为新的 version 号。
configuration 传播
哨兵完成切换之后,会在自己本地更新生成最新的 master 配置,然后同步给其他的哨兵,就是通过之前说的 pub/sub
消息机制。
这里之前的 version 号就很重要了,因为各种消息都是通过一个 channel 去发布和监听的,所以一个哨兵完成一次新的切换之后,新的 master 配置是跟着新的 version 号的。其他的哨兵都是根据版本号的大小来更新自己的 master 配置的。
110 redis 的哨兵集群 redis-cluster docker 安装
主要内容:
1 哨兵集群:https://blog.csdn.net/yaooch/article/details/80167571
a 哨兵的介绍:Sentinel(哨兵)是 Redis 的高可用性解决方案:由一个或多个 Sentinel 实例组成的 Sentinel 系统可以监视任意多个主服务器,以及这些主服务器属下的所有从服务器,并在被监视的主服务器进入下线状态时,自动将下线主服务器属下的某个从服务器升级为新的主服务器。
b :redis 哨兵配置步骤如下:
1 准备三个 redis 实例,创建三个 redis 配置文件,文件内容如下
port 6379
daemonize yes
logfile "6379.log"
dbfilename "dump-6379.rdb"
dir "/var/redis/data/"
daemonize yes
注意:这是主库的配置文件,两个从库的配置文件加上: slaveof 127.0.0.1 6379
2 启动三个 reids 实例: redis-server redis-6379.conf
3 检查三个实例的主从身份: redis-cli -p 6379 info replication
4 配置三个哨兵: redis-sentinel-26379.conf 26380.conf, 26381.conf, 文件内容如下:


// Sentinel节点的端口
port 26379
dir /var/redis/data/
logfile "26379.log"
// 当前Sentinel节点监控 127.0.0.1:6379 这个主节点
// 2代表判断主节点失败至少需要2个Sentinel节点节点同意
// mymaster是主节点的别名
sentinel monitor mymaster 127.0.0.1 6379 2
//每个Sentinel节点都要定期PING命令来判断Redis数据节点和其余Sentinel节点是否可达,如果超过30000毫秒30s且没有回复,则判定不可达
sentinel down-after-milliseconds mymaster 30000
//当Sentinel节点集合对主节点故障判定达成一致时,Sentinel领导者节点会做故障转移操作,选出新的主节点,
原来的从节点会向新的主节点发起复制操作,限制每次向新的主节点发起复制操作的从节点个数为1
sentinel parallel-syncs mymaster 1
//故障转移超时时间为180000毫秒
sentinel failover-timeout mymaster 180000
daemonize yes
三个哨兵的配置文件只是端口的不同
5 启动三个哨兵: redis-sentinel redis-sentinel-26379.conf
6 检查哨兵身份信息,检查主从节点健康状态
7 配置完成后,杀死 master 节点,查看主从身份切换是否正常.
2 redis-cluster: https://blog.csdn.net/openbox2008/article/details/80033439
a : 数据分区的介绍: 在介绍 redis cluster 之前,简单介绍分布式数据库的数据分区。所谓的数据分区就是将一个较大的数据集分布在不同的节点上进行缓存。常见的数据分区方式:节点取余,一致性哈希,虚拟槽:在 redis cluster 中使用槽来存储一定范围内的数据集,每个节点上有一定数量的槽。当客户端提交数据时,要根据 crc16 (key)&16383 来计算出数据要落在哪个虚拟槽内。与节点取余和一致性哈希分区不同,虚拟槽分区是服务端分区。客户端可以将数据提交到任意一个 redis cluster 节点上,如果存储该数据的槽不在这个节点上,则返回给客户端目标节点信息,告知客户端向目标节点提交数据。
b : 集群角色有 Master 和 Slave。Master 之间分配 slots,一共 16384 个 slot。Slave 向它指定的 Master 同步数据,实现备份。当其中的一个 Master 无法提供服务时,该 Master 的 Slave 讲提升为 Master,保证集群间 slot 的完整性。一旦其中的某一个 Master 和它的 Slave 都失效,导致了 slot 不完整,集群失效,这时就需要人工去处理了。
c : 为什么要用集群 https://blog.csdn.net/shenjianxz/article/details/59775212
数据量太大,一台服务器的内存是 16-256g, 假如业务需要 500g, 此时应该把数据分到不同的位置,分摊集中式的压力,一堆机器干一件事.
并发问题.redis 官方生成可以达到 10 万 / 每秒,每秒执行 10 万条命令,假如美妙执行 100 万条命令.
d : redis 使用中遇到的瓶颈
我们日常在对于 redis 的使用中,经常会遇到一些问题
1、高可用问题,如何保证 redis 的持续高可用性。
2、容量问题,单实例 redis 内存无法无限扩充,达到 32G 后就进入了 64 位世界,性能下降。
3、并发性能问题,redis 号称单实例 10 万并发,但也是有尽头的。
e : redis-cluster 的优势
1、官方推荐,毋庸置疑。
2、去中心化,集群最大可增加 1000 个节点,性能随节点增加而线性扩展。
3、管理方便,后续可自行增加或摘除节点,移动分槽等等。
4、简单,易上手。
d 集群的配置.https://www.cnblogs.com/pyyu/p/9844093.html
3 docker
6.docker 学习笔记之入门,Redis - 哨兵机制理论
主从复制的问题
Redis 复制有一个缺点,当主机 Master 宕机以后,我们需要人工解决切换,比如使用 slaveof no one 。实际上主从复制并没有实现高可用。
高可用侧重备份机器, 利用集群中系统的冗余,当系统中某台机器发生损坏的时候,其他后备的机器可以迅速的接替它来启动服务
一旦主节点宕机,写服务无法使用,就需要手动去切换,重新选取主节点,手动设置主从关系。
哨兵机制的原理及实现
Redis Sentinel 一个分布式架构,其中包含若干个 Sentinel 节点和 Redis 数据节点,每个 Sentinel 节点会对数据节点和其余 Sentinel 节点进行监控,当它发现节点不可达时,会对节点做下线标识。
如果被标识的是主节点,它还会和其他 Sentinel 节点进行 “协商”,当大多数 Sentinel 节点都认为主节点不可达时,它们会选举出一个 Sentinel 节点来完成自动故障转移的工作,同时会将这个变化实时通知给 Redis 应用方。整个过程完全是自动的,不需要人工来介入,所以这套方案很有效地解决了 Redis 的高可用问题。
基本的故障转移流程:
1)、主节点出现故障,此时两个从节点与主节点失去连接,主从复制失败。
2)、每个 Sentinel 节点通过定期监控发现主节点出现了故障
3)、多个 Sentinel 节点对主节点的故障达成一致会选举出其中一个节点作为领导者负责故障转移。
4)、Sentinel 领导者节点执行了故障转移,整个过程基本是跟我们手动调整一致的,只不过是自动化完成的。
5)、故障转移后整个 Redis Sentinel 的结构,重新选举了新的主节点
并且 Redis Sentinel 具有以下几个功能:
监控:Sentinel 节点会定期检测 Redis 数据节点、其余 Sentinel 节点是否可达
通知:Sentinel 节点会将故障转移的结果通知给应用方
主节点故障转移: 实现从节点晋升为主节点并维护后续正确的主从关系
配置提供者: 在 Redis Sentinel 结构中,客户端在初始化的时候连接的是 Sentinel 节点集合 ,从中获取主节点信息。
同时 Redis Sentinel 包含了若个 Sentinel 节点,这样做也带来了两个好处:
对于节点的故障判断是由多个 Sentinel 节点共同完成,这样可以有效地防止误判。
Sentinel 节点集合是由若干个 Sentinel 节点组成的,这样即使个别 Sentinel 节点不可用,整个 Sentinel 节点集合依然是健壮的。
但是 Sentinel 节点本身就是独立的 Redis 节点,只不过它们有一些特殊,它们不存储数据, 只支持部分命令
今天关于redis 哨兵集群、docker 入门和redis哨兵集群配置的讲解已经结束,谢谢您的阅读,如果想了解更多关于(六) Docker 部署 Redis 高可用集群 (sentinel 哨兵模式)、11.Redis 哨兵集群实现高可用、110 redis 的哨兵集群 redis-cluster docker 安装、6.docker 学习笔记之入门,Redis - 哨兵机制理论的相关知识,请在本站搜索。
本文标签: