主从复制同步

                                                                    day12    部署集群环境  

IP 规划

•  redis 服务器 ip 地址及端口规划

redisA 192.168.4.51 6351

redisB 192.168.4.52 6352

redisC 192.168.4.53 6353

redisD 192.168.4.54 6354

redisE 192.168.4.55 6355

redisF 192.168.4.56 6355

拓展图

             

集群工作原理

                             

创建 Redis 集群

装包

• 在 6 台主机上做如下配置,并运行 redis 服务

#yum -y install gcc gcc-c++

#tar -zxvf redis-4.0.8.tar.gz

#cd redis-4.0.8/

#make

#make install

#./utils/install_server.sh

• 修改配置文件

#vim /etc/redis/redis.conf

bind IP 地址                                 // 只写物理接口 IP 地址

daemonize yes                            // 守护进程方式运行

port xxxx                                      // 端口号不要使用默认的 6379

cluster-enabled yes                     // 开启集群

cluster-config-file nodes.conf      // 集群的配置文件不要使用默认的名称

cluster-node-timeout 5000          // 请求超时 5

装包: 

1)在执行创建集群命令的主机安装ruby软件包(192.168.4.51

安装解释ruby代码的软件包                                     

[root@host51 ~]#cd sofd/redis

[root@host51 ~]# yum -y install ruby  rubygems     

[root@host51 ~]# rpm -q rubygems  ruby

rubygems-2.0.14.1-30.el7.noarch

ruby-2.0.0.648-30.el7.x86_64

[root@host51redis-cluster]#rpm -ivh --nodeps ruby-devel-2.0.0.648-30.el7.x86_64.rpm


如果失败

1.先停服务

/etc/init.d/redis_6379  stop

2.删掉配置  rm -rf

/var/lib/redis/6379/nodes-6351.conf

3.起服务

/etc/init.d/redis_6379  stop


  安装ruby连接redis 接口程序 gem

[root@host51 redis-cluster]# which  gem

/usr/bin/gem

[root@host51 redis-cluster]# gem  install  redis-3.2.1.gem

Successfully installed redis-3.2.1

.....

[root@host51 redis]# redis-trib.rb  create   --replicas  1  \

                      192.168.4.51:6351 \

                      192.168.4.52:6352 \

                      192.168.4.53:6353 \

                      192.168.4.54:6354 \

                      192.168.4.55:6355 \

                      192.168.4.56:6356 \

                  [OK] All 16384 slots covered.

2)每台 redis服务 在本机登录 查看集群信息

[root@host51 ~]# redis-cli  -c -h 192.168.4.51  -p 6051

3) -c  连接集群中的主机

[root@host51 ~]# redis-cli  -c -h 192.168.4.51  -p 6051  //c连集群

192.168.4.51:6051> CLUSTER  info   # 查看集群信息

192.168.4.51:6051> CLUSTER nodes  # 查看本机信息

192.168.4.51:6051> quit

4测试集群

• 在其中任意一台上存储数据 ,在其他任意一台上都可以获取数据。

存数据 set name jerry

取数据 get name

5)查看谁是谁的从

[root@host51 ~]# cat /var/lib/redis/6379/nodes-6351.conf

>f31ac9e191df6f687e869920d4ef41d91d35b2f2 192.168.4.52:6352@16352 master - 0 1528426466000 2 connected 5461-10922

>3946ea34eda4c157d20a31d4ba8c5d00dd0f8293 192.168.4.55:6355@16355slave8a09a4308efbe3d7446b16894c35b7b283feffdc 0 1528426466817 5 connected

>1f496b03d550b7c6762f661893b011bf05cec65f 192.168.4.53:6353@16353 master - 0 1528426467821 3 connected 10923-16383

>797394b58fb1172f853d25477c2781f87d2fc57f 192.168.4.56:6356@16356 slave f31ac9e191df6f687e869920d4ef41d91d35b2f2 0 1528426466000 6 connected

>8a09a4308efbe3d7446b16894c35b7b283feffdc 192.168.4.51:6351@16351 myself,master - 0 1528426467000 1 connected 0-5460

>462a971184ceb3fd1def7a7b72069225a95cf14c 192.168.4.54:6354@16354 slave 1f496b03d550b7c6762f661893b011bf05cec65f 0 1528426468000 4 connected

vars currentEpoch 6 lastVoteEpoch 0

  • 从上得出:

        

51        55

52        56

53        54

  •  储存规律     

192.168.4.52:6352> set n 40

-> Redirected to slot [3432] located at 192.168.4.51:6351

OK

192.168.4.51:6351> keys *

1) "n"

192.168.4.51:6351> get n

"40"                                                   


 注意:

n  crc16 3  %  16383  0-5460

(决定存在51自动调51


 管理命令

redis-cli 命令

• 查看命令帮助

redis-cli -h

• 常用选项

-h IP  地址

-p    端口

-c    访问集群redis-trib.rb 脚本

• 语法格式

Redis-trib.rb

选项 参数

• 选项

add-node 添加新节点

check 对节点主机做检查

reshard 对节点主机重新分片

add-node --slave 添加从节点主机

del-node 删除节点主机

例子:

1)添加集群主库

[root@host51src]#./redis-trib.rb add-node 192.168.4.50:6350 192.168.4.51:6351

2)删除集群主库

[root@host51 src]# redis-trib.rb del-node 192.168.4.51:6351 3bbad4f4aa9fee1f78a9f266458b163095c786ae

3)添加集群从库

添加slave角色主机

1  主机运行redis服务 并设置集群配置

2  添加slave角色主机

]# redis-trib.rb add-node --slave     要添加到集群中主机ip:端口     集群中已有的任意一个主机的ip:端口

[root@host51 src]#./redis-trib.rb add-node --slave 192.168.4.57:6357 192.168.4.51:6351

4)重新分片

 

 

删除节点主机

1  删除master角色的节点主机

1.1 移除占用的hash槽(slot

1.2 删除主机


还原主从集群: 

rm -rf /var/lib/redis/6379/*

/etc/init.d/redis_6379 stop

/etc/init.d/redis_6379 start


 ]#redis-trib.rb  reshard  192.168.4.51:6051

4096          移除hash槽的个数

主机id       目标主机id

主机id       源主机id

done         设置完毕

yes            提交

[root@host51 src]# ./redis-trib.rb reshard 192.168.4.51:6351

How many slots do you want to move (from 1 to 16384)? 4096

What is the receiving node ID? 新的主机,分配4096个糟

Source node #1: 从多的主机节点分配,这里填要分配的ipyes分配

5)察看分配结果  ,检查集群主机状态信息

[root@host51 src]# redis-trib.rb  check  192.168.4.51:6351

                  主从复制概述      day13

  • 拓扑结构

主服务器数据自动同步到从服务器

  • 主从复制工作原理

• 工作原理

Slave maste 发送 sync 命令

Master 启动后台存盘进程,同时收集所有修改数据命令

Master 执行完后台存盘进程后,传送整个数据文件到slave

Slave 接收数据文件后,将其存盘并加载到内存中完成首次完全同步

– 后续有新数据产生时, master 继续将新的所以收集到的修改命令依次传给 slave ,完成同步。主从复制缺点

• 缺点

– 网络繁忙,会产生数据同步延时问题

– 系统繁忙,会产生数据同步延时问题

  • 配置从库

配置从库 192.168.4.52/24

redis 服务运行后,默认都是 master 服务器

– 修改服务使用的 IP 地址 bind 192.168.4.X

[root@redis52 ~]# redis-cli -h 192.168.4.52 -p 6352

192.168.4.52:6379> info replication   // 查看主从配置信息

192.168.4.52:6379> SLAVEOF 192.168.4.51 6351

OK                                     

192.168.4.52:6379> info replication          命令行指定主库

# Replication                                 SLAVEOF 主库 IP 地址 端口号

role:slave 

master_host:192.168.4.51

master_port:6379反客为主


 重起服务变成主库: 

/etc/init.d/redis_6379 stop

/etc/init.d/redis_6379 start


 

  • 反客为主

• 反客为主

– 主库宕机后,手动将从库设置为主库

[root@redis52 ~]# redis-cli -h 192.168.4.52

192.168.4.52:6379> SLAVEOF no one    // 设置为主库

OK

192.168.4.52:6379> info replication

# Replication

role:master

  • 哨兵模式

• 哨兵模式                               

– 主库宕机后,从库自动升级为主库

– 在 slave 主机编辑 sentinel.conf 文件

– 在 slave 主机运行哨兵程序

[root@redis52 ~]# vim /etc/sentinel.conf

sentinel monitor redis51 192.168.4.51 6379 1

:wq

[root@redis52 ~]# redis-sentinel /etc/sentinel.conf

  • 配置带验证的主从复制

• 配置 master 主机

– 设置连接密码 ,启动服务,连接服务

[root@redis51 ~]# sed -n '70p;501p' /etc/redis/6379.conf

bind 192.168.4.51

requirepass 123456 // 密码

[root@redis51 ~]# /etc/init.d/redis_6379 start

Starting Redis server...

[root@redis51 ~]# redis-cli -h 192.168.1.111 -a 123456 -p 6379

192.168.4.51:6379>

配置文件,脚本停服务

[root@host51 ~]#  redis-cli -h 192.168.4.51 -a 123456 -p 6351 shutdown

[root@host51 ~]# vim /etc/init.d/redis_6379  

   ... ...

   $CLIEXEC -h 192.168.4.51 -p 6351 -a 123456 shutdown

[root@redis51 ~]# /etc/init.d/redis_6379 start


 配置带验证的主从复制 ( 续 1 )

• 配置 slave 主机

– 指定主库 IP ,设置连接密码,启动服务

[root@redis52 ~]# sed -n '70p;282p;289p' /etc/redis/6379.conf

bind 192.168.4.52

slaveof 192.168.4.51 6379 // 主库 IP 与端口

masterauth 123456 // 主库密码

[root@redis52 ~]#

[root@redis52 ~]# /etc/init.d/redis_6379 start

Starting Redis server...

[root@redis52 ~]# redis-cli -h 192.168.4.52

192.168.4.52:6379> INFO replication

# Replication

role:slave

master_host:192.168.4.51

master_port:6379 


 持久化之 RDB

  • RDB 介绍

• 全称 Reids DataBase

– 数据持久化方式之一

– 在指定时间间隔内,将内存中的数据集快照写入硬盘。

– 术语叫 Snapshot 快照。

– 恢复时,将快照文件直接读到内存里。

  • 相关配置参数 (  /var/lib/redis/6379/dump.rdb)

• 文件名

dbfilename dump.rdb// 文件名

save “”                 // 禁用 RDB

• 数据从内存保存到硬盘的频率

save 900 1                // 900 秒内且有 1 次修改存盘

save 300 10               //300 秒内且有 10 次修改存盘

save 60 10000            //60 秒内且有 10000 修改存盘

• 手动立刻存盘

> save       // 阻塞写存盘

> bgsave    // 不阻塞写存盘

  • 相关配置参数 ( 1)

• 压缩

rdbcompression yes | no

• 在存储快照后,使用 crc16 算法做数据校验

rdbchecksum yes|no

bgsave 出错停止写操作 , 对数据一致性要求不高设置为 no

stop-writes-on-bgsave-error yes|no

  • 使用 RDB 文件恢复数据

• 备份数据

– 备份 dump.rdb 文件到其他位置

~]# cp 数据库目录 /dump.rdb

  • 备份目录

• 恢复数据

– 把备份的 dump.rdb 文件拷贝回数据库目录 , 重启 redis 服务

cp 备份目录 /dump.rdb 数据库目录 /

/etc/redid/redis_ 端口 start


 例子:

[root@host53 ~]# redis-cli -h 192.168.4.53 -p 6353

192.168.4.53:6353> set v1 11

192.168.4.53:6353> save

[root@host53 6379]# cp dump.rdb dump.rdb.back

192.168.4.53:6353>  flushall

[root@host53 6379]#  /etc/init.d/redis_6379  stop

[root@host53 6379]# cp dump.rdb.back dump.rdb

[root@host53 6379]#  /etc/init.d/redis_6379  start


  • RDB 优点 / 缺点

RDB 优点

– 持久化时, Redis 服务会创建一个子进程来进行持久化,会先将数据写入到一个临时文件中,待持久化过程都结束了,再用这个临时文件替换上次持久化好的文件;整个过程中主进程不做任何 IO 操作,这就确保了极高的性能。

– 如果要进程大规模数据恢复,且对数据完整行要求不是非常高,使用 RDB AOF 更高效。

RDB 的缺点

– 意外宕机,最后一次持久化的数据会丢失。

 

持久化之 AOF

  • AOF 介绍

• 只追加操作的文件

Append Only File

– 记录 redis 服务所有写操作。

– 不断的将新的写操作,追加到文件的末尾。

– 使用 cat 命令可以查看文件内容

• 相关配置参数 

  [root@host53 6379]# sed -n '673p'  /etc/redis/6379.conf

• 文件名

appendfilename "appendonly.aof" // 文件名

appendonly yes // 启用 aof ,默认 no

AOF 文件记录,写操作的三种方式

appendfsync always // 有新的写操作立即记录,性能差,完整性好。

appendfsync everysec // 每秒记录一次,宕机时会丢失 1 秒的数据

appendfsync no // 从不记录

  • 相关配置参数 ( 1)

• 日志重写 ( 日志文件会不断增大 ) ,何时会触发日志重写?

redis 会记录上次重写时 AOF 文件的大小,默认配置

是当 aof 文件是上次 rewrite 后大小的 1 倍且文件大于

64M 时触发。

auto-aof-rewrite-percentage 100

auto-aof-rewrite-min-size 64mb

  • 相关配置参数 ( 2)

• 修复 AOF 文件,

– 把文件恢复到最后一次的正确操作

[root@redis53 6379]# redis-check-aof --fix appendonly.aof

0x83: Expected \r\n, got: 6166

AOF analyzed: size=160, ok_up_to=123, diff=37

This will shrink the AOF from 160 bytes, with 37 bytes, to 123

bytes

Continue? [y/N]: y

Successfully truncated AOF

• 备份数据

– 备份 dump.rdb 文件到其他位置

~]# cp 数据库目录  /appendonly.aof

备份目录

• 恢复数据

– 把备份的 dump.rdb 文件拷贝回数据库目录 , 重启 redis 服务

– cp  备份目录/appendonly.aof  数据库目录 /

/etc/redid/redis_ 端口 start

  • AOF 优点 / 缺点

RDB 优点

– 可以灵活的设置同步持久化 appendfsync alwayls

异步持久化 appendfsync verysec

– 宕机时,仅可能丢失 1 秒的数据

RDB 的缺点

AOF 文件的体积通常会大于 RDB 文件的体积。执行 fs

ync 策略时的速度可能会比 RDB 慢。

************************************************************************

例子:

[root@host53 ~]# redis-cli -h 192.168.4.53 -p 6353

192.168.4.53:6353> set v1 11

192.168.4.53:6353> save

[root@host53 6379]# cp dump.rdb dump.rdb.back

192.168.4.53:6353>  flushall

1.删掉一些数据进行修复

[root@redis53 6379]#  vim appendonly.aof

[root@redis53 6379]#  redis-check-aof --fix appendonly.aof

[root@host53 6379]#  /etc/init.d/redis_6379  stop

[root@host53 6379]#  /etc/init.d/redis_6379  start

2.完整恢复

[root@host53 6379]#  /etc/init.d/redis_6379  stop

[root@host53 6379]#  cp dump.rdb.back dump.rdb

[root@host53 6379]#  /etc/init.d/redis_6379  start

**********************************************************************


 String 字符串

  • 字符串操作

set key value [ex seconds] [px milliseconds] [nx|xx]

– 设置 key 及值,过期时间可以设置为秒或毫秒为单位

nx 只有 key 不存在,才对 key 进行操作          

xx 只有 key 已存在,才对 key 进行操作         

setrange key offset value                     

– 从偏移量开始复写 key 的特定位的值             

>set first "hello world"

>setrange first 6  “Redis”  // 改写为 hello Redis

strlen key

 – 统计字串长度

>strlen first

  • 字符串操作(1 )

append key value

– 字符存在则追加,不存在则创建 key value

– 返回值为 key 的长度

>append myname jacob

setbit key offset value

– 对 key 所存储字串,设置或清除特定偏移量上的位 (bit)

Value 值可以为 1 0 , offset 0~2^32 之间

key 不存在,则创建新 key

>setbit bit 0 1   //尾数1,计数1

>setbit bit 1 0   //尾数0,不记数

>bitcount bit    // 结果为 2   

bit: 0 位为 1 ,第一位为 0

  • 字符串操作(2 )

bitcount key

– 统计字串中被设置为 1 的比特位数量

>setbit bits 0 1   //0001

>setbit bits 3 1   //1001

>bitcount bits    // 结果为 2

记录网站用户上线频率,如用户 A 上线了多少天等类似的数据如用户在某天上线,则使用 setbit ,以用户名为 key ,将网站上线日为 offset ,并在该 offset 上设置 1 ,最后计算用户总上线次数时,使用 bitcount 用户名即可这样,即使网站运行 10 ,每个用户仅占用 10*365 比特位即 456字节即可

>setbit peter 100 1  // 网站上线 100 天用户登录了一次

>setbit peter 105 1  // 网站上线 105 天用户登录了一次

>bitcount peter      //网站上线peter 用户总登录了2

  • 字符串操作(3 )

decr key

– 将 key 中的值减 1 , key 不存在则先初始化为 0 ,再减 1

>set test 10                            

>decr test                              

decrby key decrement                

– 将 key 中的值,减去 decrement        

>set count 100                       

>decrby count 20                       

get key

– 返回 key 所存储的字符串值

– 如果 key 不存在则返回特殊值 nil

– 如果 key 的值不是字串,则返回错误, get 只能处理字串


 例子: 

>set  test 10 

>decr test (10-1=9)

(integer) 9

> decrby test 3 

(integer) 6


 字符串操作(续 4 )

getrange key start end

– 返回字串值中的子字串,截取范围为 start end

– 负数偏移量表述从末尾计数, -1 表示最后一个字符, -2表示倒数第二个字符

>set first "hello,the world"

>getrange first -5 -1

"world"   //最后的1到五位

>getrange first 0 4

"hello"   //0.1.2.3.4

>getrange first 10 15

"world"  //10位到15

  • 字符串操作(5 )

incr key

– 将 key 的值加 1 ,如果 key 不存在,则初始为 0 后再加 1

– 主要应用为计数

>set page 20

>incr page          //后面不附值,默认执行一次加1,结果为21

incrby key increment

– 将 key 的值增加 increment

>incrby  page 2    //执行一次值加2

  • 字符串操作(6 )

incrbyfloat key increment

– 为 key 中所储存的值加上浮点数增量 increment

>set num 16.1

>incrbyfloat num 1.1

"17.2"

mget key [key...]

– 一次获取一个或多个 key 的值,空格分隔, < 具有原子性>

mset key value [key value ...]

– 一次设置多个 key 及值,空格分隔, < 具有原子性 >


 例子:

set iphone "1234564345"

setrange iphone 3  ****

get iphone 


 Hash 表

  • Hash 表简介

Redis hash 是一个 string 类型的 field value 的映射表

• 一个 key 可对应多个 field ,一个 field 对应一个 value

• 将一个对象存储为 hash 类型,较于每个字段都存储成string 类型更能节省内存

  • Hash 表操作

hset key field value

– 将 hash 表中 field 值设置为 value

>hset site google 'www.g.cn’

>hset site baidu 'www.baidu.com'

hget key filed

– 获取 hash 表中 field 的值

>hget site google

  • Hash 表操作(1 )

hmset key field value [field value...]

– 同时给 hash 表中的多个 field 赋值

>hmset site google  www.g.cn baidu  www.baidu.com

hmget key field [field...]

– 返回 hash 表中多个 field 的值

>hmget site google baidu

hkeys key

– 返回 hash 表中所有 field 名称

>hmset site google www.g.cn baidu www.baidu.com

>hkeys site

  • Hash 表操作(2 )

hgetall key

1) "google"

2) "www.g.cn"

3) "baidu"

4) "www.baidu.com"

– 返回 hash 表中所有 field 的值

hvals key

1) "www.g.cn"

2) "www.baidu.com"

– 返回 hash 表中所有 filed 的值

>hvals key

hdel key field [field...]

– 删除 hash 表中多个 field 的值,不存在则忽略

>hdel site google baidu


 List 列表

List 列表简介

Redis list 是一个字符队列

• 先进后出                                                   注意:

• 一个 key 可以有多个值                              正数,最后第一个往前输出

lpush key value [value...]                              负数,第一个往后输

– 将一个或多个值 value 插入到列表 key 的表头

Key 不存在,则创建 key

>lpush list a b c        //list1 值依次为 c b a

等同于 lpush list a; lpush list b; lpush list c

lrange key start stop

– 从开始位置读取 key 的值到 stop 结束

>lrange list 0 2       // 0 位开始,读到 2 位为止

>lrange list 0 -1      // 从开始读到结束为止 ,输出到最后第一个输出的值

>lrange list 0 -2      // 从开始读到倒数第 2 位值,到最开始第一个不输出

>type list            //列表类型

  • List 列表操作(1 )

lpop key

– 移除并返回列表头元素数据, key 不存在则返回 nil

>lpop list    // 删除表头元素,可以多次执行

llen key

– 返回列表 key 的长

  • List 列表操作(2 )

lindex key index

– 返回列表中第 index 个值

lindex key 0 ; lindex key 2; lindex key -2

lset key index value

– 将 key index 位置的值修改为 value

>lset list 3 test   // list 中第 3 个值修改为 test

  • List 列表操作(3 )

rpush key value [value...]

– 将 value 插入到 key 的末尾

>rpush list3 a b c    //list3 值为 a b c

>rpush list3 d       // 末尾插入 d

rpop key

– 删除并返回 key 末尾的值

>rpush list3 a b c //list3 值为 a b c

>rpush list3 d    // 末尾插入 d


 

其他操作

其他操作指令

del key [key...]

– 删除一个或多个 key

exists key

– 测试一个 key 是否存在

expire key seconds

– 设置 key 的生存周期

persist key

– 设置 key 永不过期

ttl key

– 查看 key 的生存周期


 

  • 其他操作指令(1 )

keys 匹配

– 找符合匹配条件的 key ,特殊符号用 \ 屏蔽

>keys *        // 显示所有 key

>keys h?llo    // 匹配 hello,hallo,hxllo

>keys h*llo    // 匹配 hllo heeello

>keys h[ae]lo  // 匹配 hello hallo

flushall

– 清空所有数据

select id

– 选择数据库, id 用数字指定,默认数据库为 0

>select 0

>select 2

  • 其他操作指令(2 )

move key db_id

– 将当前数据库的 key 移动到 db_id 数据库中

>move key 1    // key 移动到 1 数据库中

rename key newkey

– 给 key 改名为 newkey , newkey 已存在时,则覆盖其值

renamenx key newkey

– 仅当 newkey 不存在时,才将 key 改名为 newkey

  • 其他操作指令(3 )

sort key

– 对 key 进行排序

>lpush cost 1 8 7 2 5

>sort cost                        // 默认对数字排序,升序

>sort cost desc              // 降序

>lpush test about” “site” “rename

>sort test alpha                             // 对字符排序

>sort cost alpha limit 0 3               // 排序后提取 0-3 位数据

>sort cost alpha limit 0 3 desc      // 排序后提取倒数 0-3 位数据

>sort cost STORE cost2               // cost 排序并保存为 cost2

type key

– 返回 key 的数据类型


 案例 3 :常用 Redis 数据库操作指令

• 对 Redis 数据库各数据类型进行增删改查操作

– 数据类型分别为 Strings Hash 表、 List 列表

– 设置数据缓存时间

– 清空所有数据

– 对数据库操作


数据类型

数据类型总结

• 字符类型

hash 表类型

List 列表类型

 

管理命令

管理命令总结

del key [key...]

– 删除一个或多个 key

exists key

– 测试一个 key 是否存在

expire key seconds

– 设置 key 的生存周期

persist key

– 设置 key 永不过期

ttl key

– 查看 key 的生存周期

posted @ 2019-12-10 15:03  云计算(互联网)  Views(388)  Comments(0Edit  收藏  举报