九章——Redis群集(应用——linux防护与群集)

三期总目录链接

目录

一、Redis介绍

(一)关系型数据库与非关系型数据库

1、关系型数据库

2、非关系型数据库

3、非关系型数据库产生背景

(二)Redis基础

1、Redis简介

2、Redis的优点

3、应用场景

4、Redis安装部署

(三)Redis命令工具

 1、redis-cli命令行工具

2、redis-benchmark测试工具

(四)Redis 数据库常用命令

1、key相关命令

2、多数据库常用命令

二、Redis群集

(一)Redis群集原理

(二)部署Redis群集

1、部署环境 

2、使用脚本创建群集

复习题


一、Redis介绍

(一)关系型数据库与非关系型数据库

 数据库按照其架构可以分为关系型数据库与其他数据库,其他数据库统称为非关系型数据库

1、关系型数据库

一个结构化的数据库,创建在关系模型基础上,一般面向于记录
主流的关系型数据库有:Oracle、MySQL、SQL Server、Microsoft Access、DB2等

2、非关系型数据库

NoSQL(NoSQL=Not Only SQL):意思是“不仅仅是SQL”,是非关系型数据库的总称,它可以作为关系型数据库的良好补充;随着互联网web2.0网站的兴起,非关系型的数据库现在成了一个极其热门的新领域,非关系数据库产品的发展非常迅速。而传统的关系数据库在应付web2.0网站,特别是超大规模和高并发的SNS类型的web2.0纯动态网站已经显得力不从心,暴露了很多难以克服的问题
主流的关系型数据库有:Redis、MongBD、Hbase、CouhDB等

3、非关系型数据库产生背景

3.1 High performance——对数据库高并发读写需求

web2.0网站要根据用户个性化信息来实时生成动态页面和提供动态信息,所以基本上无法使用动态页面静态化技术,因此数据库并发负载非常高,往往要达到每秒上万次读写请求。关系数据库应付上万次SQL查询还勉强顶得住,但是应付上万次SQL写数据请求,硬盘IO就已经无法承受了。其实对于普通的BBS网站,往往也存在对高并发写请求的需求,例如网站的实时统计在线用户状态,记录热门帖子的点击次数,投票计数等,因此这是一个相当普遍的需求

3.2 Huge Storage——对海量数据高效存储与访问需求

类似Facebook,twitter,Friendfeed这样的SNS网站,每天用户产生海量的用户动态,以Friendfeed为例,一个月就达到了2.5亿条用户动态,对于关系数据库来说,在一张2.5亿条记录的表里面进行SQL查询,效率是极其低下乃至不可忍受的。再例如大型web网站的用户登录系统,例如腾讯,盛大,动辄数以亿计的帐号,关系数据库也很难应付

3.3 High Scalability && High Availability——对数据库高可扩展性与高可用性需求

在web的架构当中,数据库是最难进行横向扩展的,当一个应用系统的用户量和访问量与日俱增的时候,你的数据库却没有办法像web server和app server那样简单的通过添加更多的硬件和服务节点来扩展性能和负载能力。对于很多需要提供24小时不间断服务的网站来说,对数据库系统进行升级和扩展是非常痛苦的事情,往往需要停机维护和数据迁移,其工作量是非常庞大的

关系型数据库和非关系型数据库都有各自的特点与应用场景,两者的紧密结合将会给 Web 2.0的数据库发展带来新的思路。
让关系型数据库关注在关系上,非关系型数据库关注在存储上

(二)Redis基础

1、Redis简介

Redis是一个开源的、使用c语言编写、支持网络、基于内存运行并支持持久化的日志型,采用key-value(键值对)数据库

2、Redis的优点

1)具有极高的数据读写速度

redis是将数据存放到内存中,由于内容存取速度快所以redis被广泛应用在互联网项目中,redis优点:存取速度快,官方称读取速度会达到30万次每秒,写速度在10万次每秒最少,具体限制于硬件

2)支持丰富的数据类型

redis是用C语言开发的一个开源的高性能键值对(key-value)数据库。它通过提供多种键值数据类型来适应不同场景下的存储需求,目前Redis支持的键值数据类型有字符串类型 散列类型 列表类型 集合类型

3)支持数据的持久化

可以将内存中的数据异步写入到硬盘中,同时不影响继续提供服务
缺点:对持久化支持不够良好
所以redis一般不作为数据的主数据库存储,一般配合传统的关系型数据库使用

4)原子性

redis的所有操作都是原子性的

5)支持数据备份

master-slave模式的数据备份

6)功能丰富

Redis可以为每个键设置生存时间,时间到期后该键被自动删除,这一功能配合出色的性能让Redis可以作为缓存系统来用
作为缓存系统,Redis还可以限定数据占用的最大内存空间,在数据达到空间限制后可以按照一定的规则自动淘汰不需要的键。
Redis的列表类型键可以用来实现队列,并且支持阻塞式读取,可以很容易的实现一个高性能的优先级队列
Redis还支持“发布/订阅”的消息模式

3、应用场景

Redis 作为基于内存运行的数据库,缓存是其较常应用的场景之一,除此之外,Redis常见应用场景还包括获取最新N个数据的操作.排行榜类应用.计数器应用、存储关系、实时分析系统,日志记录等

适用场景:数据高并发的读写;海量数据的读写;对扩展性要求高的数据

4、Redis安装部署

编译安装redis

[root@C7-06 ~]# tar xf redis-3.2.9.tar.gz -C /usr/src
[root@C7-06 ~]# cd /usr/src/redis-3.2.9/
[root@C7-06 redis-3.2.9]# ls       #查看
00-RELEASENOTES  CONTRIBUTING  deps     Makefile   README.md   runtest          runtest-sentinel  src    utils
BUGS             COPYING       INSTALL  MANIFESTO  redis.conf  runtest-cluster  sentinel.conf     tests

源码包提供了makefile文件,直接编译安装即可

[root@C7-06 redis-3.2.9]# make
.......
...
[root@C7-06 redis-3.2.9]# make install
cd src && make install
make[1]: 进入目录“/usr/src/redis-3.2.9/src”

Hint: It's a good idea to run 'make test' ;)

    INSTALL install
    INSTALL install
    INSTALL install
    INSTALL install
    INSTALL install
make[1]: 离开目录“/usr/src/redis-3.2.9/src”

说明:在安装过程中,如果想更改默认路径可以使用下面的命令格式:

made PREFIX=安装路径 install

make install 只是安装了二进制文件到系统中,没有启动脚本和配置文件;软件包中默认提供了一个install_server脚本文件,通过该脚本可以设置Redis服务所需要的相关配置文件

[root@C7-06 redis-3.2.9]# cd /usr/src/redis-3.2.9/utils/
[root@C7-06 utils]# ls
build-static-symbols.tcl  generate-command-help.rb  lru                    redis-sha1.rb
cluster_fail_time.tcl     hashtable                 redis-copy.rb          releasetools
corrupt_rdb.c             hyperloglog               redis_init_script      speed-regression.tcl
create-cluster            install_server.sh         redis_init_script.tpl  whatisdoing.sh
  
[root@C7-06 utils]# ./install_server.sh       #启动脚本
Welcome to the redis service installer
This script will help you easily set up a running redis server

Please select the redis port for this instance: [6379]                    #默认侦听端口
Selecting default: 6379
Please select the redis config file name [/etc/redis/6379.conf]           #默认配置文件
Selected default - /etc/redis/6379.conf
Please select the redis log file name [/var/log/redis_6379.log]           #日志文件
Selected default - /var/log/redis_6379.log
Please select the data directory for this instance [/var/lib/redis/6379]  #数据库目录
Selected default - /var/lib/redis/6379
Please select the redis executable path [/usr/local/bin/redis-server]     #执行命令
Selected config:
Port           : 6379
Config file    : /etc/redis/6379.conf
Log file       : /var/log/redis_6379.log
Data dir       : /var/lib/redis/6379
Executable     : /usr/local/bin/redis-server
Cli Executable : /usr/local/bin/redis-cli                                 #客户端命令
Is this ok? Then press ENTER to go on or Ctrl-C to abort.
Copied /tmp/6379.conf => /etc/init.d/redis_6379
Installing service...
Successfully added to chkconfig!


Successfully added to runlevels 345!
Starting Redis server...

Installation successful!

[root@C7-06 utils]# netstat -anpt|grep redis    #查看redis端口
tcp        0      0 127.0.0.1:6379          0.0.0.0:*               LISTEN      4750/redis-server 1 

安装完成后可以使用/etc/init.d/redis_6379 来进行启动、停止、重启服务

[root@C7-06 utils]# /etc/init.d/redis_6379 stop    #停止服务
Stopping ...
Redis stopped
[root@C7-06 utils]# netstat -anpt|grep redis

[root@C7-06 ~]# /etc/init.d/redis_6379 start       #启动服务
Starting Redis server...
[root@C7-06 ~]# netstat -anpt|grep redis
tcp        0      0 127.0.0.1:6379          0.0.0.0:*               LISTEN      4946/redis-server 1 

[root@C7-06 ~]# /etc/init.d/redis_6379 restart    #重启服务
Stopping ...
Redis stopped
Starting Redis server...

[root@C7-06 ~]# /etc/init.d/redis_6379 status     #查看状态
Redis is running (4974)

编辑redis主配置文件:绑定当前ip地址(只修改ip其他为介绍)

[root@C7-06 ~]# vim /etc/redis/6379.conf

......
...
bind 127.0.0.1 192.168.1.1                    #添加本机地址:192.168.1.1   在62行
.......
...

保存退出

[root@C7-06 ~]# /etc/init.d/redis_6379 restart   #重启服务
Stopping ...
Redis stopped
Starting Redis server...

 如果出现 Could not connect to Redis at 127.0.0.1:6379: Connection refused 的报错

[root@C-06 utils]# redis-cli
Could not connect to Redis at 127.0.0.1:6379: Connection refused
Could not connect to Redis at 127.0.0.1:6379: Connection refused
not connected>

打开配置文件找到 daemonize  no  修改为daemonize yes  这样就可以默认启动后台运行

 redis主配置文件解释

[root@C7-06 ~]# grep -v "^#" /etc/redis/6379.conf | grep -v "^$"
bind 192.168.1.1                     #监听的主机地址
protected-mode yes                   #是否开启保护模式,默认开启,已指定bind和密码:只会本地进行访问,拒绝外部访问,未指定bind和密码:最好关闭,设置为no
port 6379                            #监听端口
tcp-backlog 511                      #TCP连接中已完成队列(完成三次握手之后)的长度
timeout 0                            #客户端闲置多长时间后关闭连接,0为关闭该功能
tcp-keepalive 300                    #定时给对端端口发送ack。检测到对端关闭需要两倍的设置值
daemonize yes                        #启用守护进程
supervised no                        #可以通过upstart和systemd管理Redis守护进程.这个参数是和具体的操作系统相关的
pidfile /var/run/redis_6379.pid      #指定PID文件;redis的进程文件
loglevel notice                      #指定PID文件;服务端日志的级别 debug(很多信息,方便开发、测试);verbose(许多有用的信息,但是没有debug级别信息多);notice(适当的日志级别,适合生产环境),warn(只有非常重要的信息)
logfile /var/log/redis_6379.log      #指定记录日志的文件
databases 16                         #数据库的数量,默认使用的数据库是DB 0
save 900 1                           #数据持久化配置,将内存中数据写入到数据库中(15分钟)内至少1个key值改变(则进行数据库保存--持久化)
save 300 10                          #(5分钟)内至少10个key值改变(则进行数据库保存--持久化)
save 60 10000                        #(1分钟)内至少10000个key值改变(则进行数据库保存--持久化)
stop-writes-on-bgsave-error yes      #当RDB持久化出现错误后,依然进行继续进行工作;(否则为no)
rdbcompression yes                   #使用压缩rdb文件,rdb文件压缩使用LZF压缩算法,yes:压缩,但是需要一些cpu的消耗。no:不压缩,需要更多的磁盘空间
rdbchecksum yes                      #是否校验rdb文件。从rdb格式的第五个版本开始,在rdb文件的末尾会带上CRC64的校验和。这跟有利于文件的容错性,但是在保存rdb文件的时候,会有大概10%的性能损耗,所以如果你追求高性能,可以关闭该配置
dbfilename dump.rdb                  #rdb文件的名称
dir /var/lib/redis/6379              #数据目录,数据库的写入会在这个目录。rdb、aof文件也会写在这个目录
slave-serve-stale-data yes           #从库同主机失去连接或者复制正在进行,从机库有两种运行方式:1、如果slave-serve-stale-data设置为yes(默认设置),从库会继续响应客户端的请求。2、 如果slave-serve-stale-data设置为no,除去INFO和SLAVOF命令之外的任何请求都会返回一个错误”SYNC with master in progress”
slave-read-only yes                #作为从服务器,默认情况下是只读的(yes),可以修改成NO,用于写(不建议)
repl-diskless-sync no              #是否使用socket方式复制数据。目前redis复制提供两种方式,disk和socket。如果新的slave连上来或者重连的slave无法部分同步,就会执行全量同步,master会生成rdb文件。有2种方式:disk方式是master创建一个新的进程把rdb文件保存到磁盘,再把磁盘上的rdb文件传递给slave。socket是master创建一个新的进程,直接把rdb文件以socket的方式发给slave。disk方式的时候,当一个rdb保存的过程中,多个slave都能共享这个rdb文件。socket的方式就的一个个slave顺序复制。在磁盘速度缓慢,网速快的情况下推荐用socket方式
repl-diskless-sync-delay 5         #diskless复制的延迟时间,防止设置为0。一旦复制开始,节点不会再接收新slave的复制请求直到下一个rdb传输。所以最好等待一段时间,等更多的slave连上来
repl-disable-tcp-nodelay no        #是否禁止复制tcp链接的tcp nodelay参数,可传递yes或者no。默认是no,即使用tcp nodelay。如果master设置了yes来禁止tcp nodelay设置,在把数据复制给slave的时候,会减少包的数量和更小的网络带宽。但是这也可能带来数据的延迟。默认我们推荐更小的延迟,但是在数据量传输很大的场景下,建议选择yes
slave-priority 100                 #当master不可用,Sentinel会根据slave的优先级选举一个master。最低的优先级的slave,当选master。而配置成0,永远不会被选举
appendonly no                      #是否每次更新操作后进行日志记录
appendfilename "appendonly.aof"    #更新日志文件名
appendfsync everysec               #日志条件:no:操作系统进行数据缓存同步到磁盘(快)always :每次更新后手动调用fsync()将数据写到磁盘(慢,安全) everysec:每秒同步一次
no-appendfsync-on-rewrite no       #在aof重写或者写入rdb文件的时候,会执行大量IO,此时对于everysec和always的aof模式来说,执行fsync会造成阻塞过长时间,no-appendfsync-on-rewrite字段设置为默认设置为no。如果对延迟要求很高的应用,这个字段可以设置为yes,否则还是设置为no,这样对持久化特性来说这是更安全的选择。设置为yes表示rewrite期间对新写操作不fsync,暂时存在内存中,等rewrite完成后再写入,默认为no,建议yes。Linux的默认fsync策略是30秒。可能丢失30秒数据
auto-aof-rewrite-percentage 100    #aof自动重写配置。当目前aof文件大小超过上一次重写的aof文件大小的百分之多少进行重写,即当aof文件增长到一定大小的时候Redis能够调用bgrewriteaof对日志文件进行重写。当前AOF文件大小是上次日志重写得到AOF文件大小的二倍(设置为100)时,自动启动新的日志重写过程
auto-aof-rewrite-min-size 64mb     #设置允许重写的最小aof文件大小,避免了达到约定百分比但尺寸仍然很小的情况还要重写
aof-load-truncated yes             #aof文件可能在尾部是不完整的,当redis启动的时候,aof文件的数据被载入内存。重启可能发生在redis所在的主机操作系统宕机后,尤其在ext4文件系统没有加上data=ordered选项(redis宕机或者异常终止不会造成尾部不完整现象。)出现这种现象,可以选择让redis退出,或者导入尽可能多的数据。如果选择的是yes,当截断的aof文件被导入的时候,会自动发布一个log给客户端然后load。如果是no,用户必须手动redis-check-aof修复AOF文件才可以
lua-time-limit 5000                #达到最大时间限制(毫秒),redis会记个log,然后返回error。当一个脚本超过了最大时限。只有SCRIPT KILL和SHUTDOWN NOSAVE可以用。第一个可以杀没有调write命令的东西。要是已经调用了write,只能用第二个命令杀
slowlog-log-slower-than 10000      #slowlog用来记录redis运行中执行比较慢的命令耗时。当命令的执行超过了指定时间,就记录在slow log中,slowlog保存在内存中,所以没有I/O操作。执行时间比slowlog-log-slower-than大的请求记录到slowlog里面,单位是微秒,所以1000000就是1秒
slowlog-max-len 128                #慢查询日志长度。当一个新的命令被写进日志的时候,旧记录会被删掉。这个长度没有限制。只要有足够的内存就行。可以通过 SLOWLOG RESET 来释放内存
latency-monitor-threshold 0        #延迟监控功能是用来监控redis中执行比较缓慢的一些操作,用LATENCY打印redis实例在跑命令时的耗时图表。只记录大于等于下边设置的值的操作。0为关闭监视.默认为+关闭,如果你需要打开,也可以通过CONFIG SET命令动态设置
notify-keyspace-events ""          #键空间通知使得客户端可以通过订阅频道或模式,来接收那些以某种方式改动了 Redis 数据集的事件。在默认配置下,该功能处于关闭状态
hash-max-ziplist-entries 512       #数据量小于等于512的用ziplist,大于512的用hash
hash-max-ziplist-value 64          #value大小小于等于64的用ziplist,大于64用hash
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
activerehashing yes              #是否激活重置哈希,默认开启
client-output-buffer-limit normal 0 0 0            #对客户端输出缓冲进行限制可以强迫那些不从服务器读取数据的客户端断开连接,用来强制关闭传输缓慢的客户端;对于normal client,第一个0表示取消hard limit,第二个0和第三个0表示取消soft limit,normal client默认取消限制,因为如果没有寻问,他们是不会接收数据的
client-output-buffer-limit slave 256mb 64mb 60    #slave client和MONITER client,如果client-output-buffer一旦超过256mb,又或者超过64mb持续60秒,那么服务器就会立即断开客户端连接
client-output-buffer-limit pubsub 32mb 8mb 60     #pubsub client,如果client-output-buffer一旦超过32mb,又或者超过8mb持续60秒,那么服务器就会立即断开客户端连接
hz 10                                             #redis执行任务的频率为1s除以hz
aof-rewrite-incremental-fsync yes                 #在aof重写的时候,如果打开了aof-rewrite-incremental-fsync开关,系统会每32MB执行一次fsync。这对于把文件写入磁盘是有帮助的,可以避免过大的延迟峰值

(三)Redis命令工具

[root@C7-06 ~]# ls /usr/local/bin/
redis-benchmark  redis-check-aof  redis-check-rdb  redis-cli  redis-sentinel  redis-server
Redis命令工具
redis-benchmark用于检测redis在本机的运行效率
redis-check-rdb修复RDB持久化文件
redis-sentinelredis-server的软连接
redis-check-aof修复AOF持久化文件
redis-cliredis命令行工具
redis-server用于启动redis的工具

 1、redis-cli命令行工具

  Redis数据库系统也是一个典型的C/S(客户端/服务器端)架构的应用,要访问Redis数据库需要使用专门的客户端软件。Redis服务的客户端软件就是其自带的redis-cli命令行工具,使用redis-cli连接指定数据库,连接成功后会进入提示符为‘远程主机IP地址:端口号> 的数据库操作环境

redis-cli参数
-h远程主机
-p服务端口
-a用户密码

 在数据库环境,使用help命令可以获取命令类型的帮助:
help @<group>:获取<group>中的命令列表
help <command>:获取某个命令的帮助
help <tab>:获取可能帮助的主题列表

[root@C-06 utils]# redis-cli   #连接本机上的Redis数据库
127.0.0.1:6379> ping           #检测redis服务是否启动
PONG
127.0.0.1:6379> quit          #退出或exit

[root@C-06 utils]# redis-cli -h 192.168.1.6 -p 6379     #远程访问redis数据库
192.168.1.6:6379> ping 
PONG

 help的操作方法

[root@C-06 ~]# redis-cli -h 192.168.1.6 -p 6379
192.168.1.6:6379> info             #查看服务的统计信息
# Server
redis_version:3.2.9
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:e51dc1af8ff81889
redis_mode:standalone
os:Linux 3.10.0-693.el7.x86_64 x86_64
arch_bits:64
multiplexing_api:epoll
gcc_version:4.8.5
.....
...

192.168.1.6:6379> help @list     #查看所有与list数据类型相关的命令

  BLPOP key [key ...] timeout
  summary: Remove and get the first element in a list, or block until one is available
  since: 2.0.0
........
....

192.168.1.6:6379> help set      #查看set命令的帮助信息

  SET key value [EX seconds] [PX milliseconds] [NX|XX]
  summary: Set the string value of a key
  since: 1.0.0
  group: string

2、redis-benchmark测试工具

redis-benchmark测试工具的常用选项说明
选项说明
-h指定服务器主机名 (默认 127.0.0.1)
-p指定服务器端口 (默认 6379)
-s指定服务器socket(会覆盖 -h -p 设置的内容)
-a密码(密码错误之类不会直接保错,而是在操作时才会保错,这时可以使用 Redis 的 AUTH 命令再次认证)
-c指定客户端的并发数量(默认是50)
-n指定客户端请求总量(默认是100000)
-d以字节(b)的形式指定SET/GET 添加的数据的字节大小 (默认 2)
-dbnum选择一个数据库进行测试 (默认 0)
-k客户端是否使用keepalive,1为使用,0为不使用,(默认为 1)
-rSET/GET/INCR 添加数据 key, SADD 添加随机数据,keyspacelen 指定的是添加 键的数量
-P通过管道传输<numreq>请求每个请求 pipeline 的数据量(默认为1,没有 pipeline )
-q强制退出redis,仅显示query/sec 值
--csv以csv格式输出,便于后续处理
-l生成循环,永久执行测试
-t仅运行以逗号分隔的测试命令列表
-I空闲模式(ldle模式)只打开N个空闲连接并等待

使用案例

2.1、向redis服务器发送100个并发连接与100000个请求

[root@C-06 ~]# redis-benchmark -h 192.168.1.6 -p 6379 -c 100 -n 100000
====== PING_INLINE ======
  100000 requests completed in 0.59 seconds
  100 parallel clients
  3 bytes payload
  keep alive: 1
.............
......
====== MSET (10 keys) ======                #汇总信息
  100000 requests completed in 0.81 seconds #10万个请求包在0.81秒完成
  100 parallel clients                      #100个并发连接统计
  3 bytes payload
  keep alive: 1

99.20% <= 1 milliseconds                    #毫秒
99.99% <= 2 milliseconds
100.00% <= 2 milliseconds
122699.39 requests per second               #每秒处理122699个请求

2.2、测试存取大小为100B的数据包的性能

[root@C-06 ~]# redis-benchmark -h 192.168.1.6 -p 6379 -q -d 100
PING_INLINE: 173611.12 requests per second
PING_BULK: 180505.41 requests per second
SET: 164473.69 requests per second
GET: 161290.33 requests per second
INCR: 154320.98 requests per second
LPUSH: 136425.66 requests per second
RPUSH: 127713.92 requests per second
LPOP: 159489.64 requests per second
RPOP: 162601.62 requests per second
SADD: 170068.03 requests per second
SPOP: 170648.45 requests per second
LPUSH (needed to benchmark LRANGE): 157977.88 requests per second
LRANGE_100 (first 100 elements): 47824.00 requests per second
LRANGE_300 (first 300 elements): 12815.58 requests per second
LRANGE_500 (first 450 elements): 7576.33 requests per second
LRANGE_600 (first 600 elements): 5194.00 requests per second
MSET (10 keys): 115473.45 requests per second

(四)Redis 数据库常用命令

Redis数据库采用key-value(键值对)的数据存储形式

set:存放数据  基本命令格式:set key value
get:获取数据  基本命令格式:get key

192.168.1.6:6379> set aaa c4    #在当前数据库下存放一个key为aaa,value为c4的数据
OK
192.168.1.6:6379> get aaa       #查看刚才的数据

1、key相关命令

1.1、keys

使用keys命令可以取符合规则的键值列表,通常结合  *?

*表示任意字符   ?表示一个字符

192.168.1.6:6379> set a1 今天
OK
192.168.1.6:6379> set a2 提前
OK
192.168.1.6:6379> set a3 下课
OK
192.168.1.6:6379> set a4 了
OK
192.168.1.6:6379> set a5 哈哈哈
OK
192.168.1.6:6379> keys *        #查看当前数据库中所有键
 1) "a5"
 2) "a2"
 3) "aaa"
 4) "mylist"
 5) "key:__rand_int__"
 6) "a3"
 7) "counter:__rand_int__"
 8) "a4"
 9) "key"
10) "a1"

192.168.1.6:6379> keys a*      #查看以a开头的数据
1) "a5"
2) "a2"
3) "aaa"
4) "a3"
5) "a4"
6) "a1"

192.168.1.6:6379> keys a?     #查看以v开头后面包含任意一位字符的数据
1) "a5"
2) "a2"
3) "a3"
4) "a4"
5) "a1"

192.168.1.6:6379> keys a??    #查看以v开头后面包含任意二位字符的数据
1) "aaa"
2) "av1"

1.2、exists       判断键值是否存在

192.168.1.6:6379> exists aaa   #判断键值是否存在
(integer) 1                    #返回1为存在
192.168.1.6:6379> exists bcz
(integer) 0                    #为0不存在

1.3、del     删除当前数据库的指定key

192.168.1.6:6379> exists a1     #查看是否存在
(integer) 1
192.168.1.6:6379> del a1        #指定删除当前数据库的a1
(integer) 1
192.168.1.6:6379> exists a1     #在次查看已经被删除了
(integer) 0
192.168.1.6:6379> keys *
 1) "a5"
 2) "a2"
 3) "aaa"
 4) "mylist"
 5) "key:__rand_int__"
 6) "a3"
 7) "counter:__rand_int__"
 8) "a4"
 9) "av1"
10) "key"

1.4、type     获取key对应的value值类型

192.168.1.6:6379> type a4
string                        #字符串类型

1.5、rename  重命名

192.168.1.6:6379> keys a??      #查看
1) "aaa"
2) "av1"
192.168.1.6:6379> rename aaa a1 #重命名
OK
192.168.1.6:6379> keys a?
1) "a5"
2) "a2"
3) "a3"
4) "a4"
5) "a1"

192.168.1.6:6379> rename a3 hhh  #重命名
OK
192.168.1.6:6379> keys *         #查看
 1) "a5"
 2) "a2"
 3) "hhh"
 4) "mylist"
 5) "key:__rand_int__"
 6) "counter:__rand_int__"
 7) "a4"
 8) "a1"
 9) "av1"
10) "key"

1.6、renamenx     对已有key重命名,并检测新名是否存在。如果目标key已存在则不重命名

192.168.1.6:6379> get teacher
(nil)
192.168.1.6:6379> get a1
"c4"
192.168.1.6:6379> renamenx a1 teacher  #重命名
(integer) 1
192.168.1.6:6379> keys *               #查看
 1) "a5"
 2) "a2"
 3) "hhh"
 4) "teacher"
 5) "mylist"
 6) "key:__rand_int__"
 7) "counter:__rand_int__"
 8) "a4"
 9) "av1"
10) "key"

192.168.1.6:6379> get a1
(nil)
192.168.1.6:6379> get teacher          #查看数据
"c4"

1.7、dbsize    查看当前数据库中key的数量

192.168.1.6:6379> dbsize
(integer) 10

2、多数据库常用命令

redis支持多数据库,redis默认包含16个数据库,数据库名是用数字(0-15)来依次命名,默认连接的数据库为序号0

2.1、select     多数据库间切换

192.168.1.6:6379> select 1      
OK
192.168.1.6:6379[1]> select 15
OK
192.168.1.6:6379[15]> select 0
OK

2.2、多数据库间移动数据

 Redis的多数据库在一定程度上是相对独立:在数据库15上无法查看数据库0上创建的k1数据

192.168.1.6:6379> set k1 100
OK
192.168.1.6:6379> get k1
"100"
192.168.1.6:6379> select 15
OK
192.168.1.6:6379[15]> get k1
(nil)

Redis数据库提供了一个move命令,可以进行多数据库的数据移动

192.168.1.6:6379> get k1      #查看是否存在
"100"
192.168.1.6:6379>  move k1 6  #将k1移动到数据库6中
(integer) 1
192.168.1.6:6379> select 6    #切换到数据库6
OK
192.168.1.6:6379[6]> get k1   #查看被移动的数据
"100"
192.168.1.6:6379[6]> select 0
OK
192.168.1.6:6379> get k1     #在数据库0中查看不到k1数据
(nil)

2.3、清除数据库内数据

192.168.1.6:6379[1]> keys *
1) "k1"
192.168.1.6:6379[1]> flushdb
OK
192.168.1.6:6379[1]> keys *
(empty list or set)

数据库清空操作比较危险,在生产环境中一般不建议使用。

二、Redis群集

(一)Redis群集原理

Redis Cluster是一个无中心的结构,每个节点都保存数据和整个群集的状态。每个节点都会保存其他节点的信息,知道其他节点所负责的槽,并且会与其他节点定时发送心跳信息,能够及时感知群集中异常的节点

Redis Cluster采用虚拟槽分区,将所有的数据根据算法映射到0~16383整数槽内;每个节点都保存数据和整个集群的状态

集群角色
Master:Master之间分配slots,一共有16384个slots
Slave:Slave向它指定的Master同步数据

集群节点使用的TCP端口
6379端口:用于客户端的连接
16379端口:用于群集总线,即使用二进制协议的节点到节点通信通道

节点使用群集总线进行故障检测、配置更新、故障转移授权等

(二)部署Redis群集

案例

1、部署环境 

在一台linux服务器上部署Redis集群,通过不同的TCP端口启动多实例,模拟多台独立PC组成集群

[root@C-06 ~]# /etc/init.d/redis_6379 stop    #停止服务
Stopping ...
Redis stopped

在根目录下新建/redis_cluster目录,创建集群目录,使用6个TCP端口,编写6100-6105共计6个配置文件,使用这6个配置文件启动实例,并搭建Redis集群。

注意: 这里我设置了192.168.1.1地址添加了一个vm1网卡:地址使用本机地址就可不需要添加网卡

最少6个实例才能组成集群,3主3从会自动分配

[root@C-06 ~]# mkdir -p /redis_cluster/{6100..6105}
[root@C-06 ~]# vim redis.conf          #新建编辑配置文件

bind  192.168.1.1
protected-mode yes

port 6100

tcp-backlog 511
timeout 0
tcp-keepalive 300

daemonize yes
supervised no

pidfile /redis_cluster/redis_6100.pid

loglevel notice

logfile /redis_cluster/6100/redis_6100.log


databases 16
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb

dir /redis_cluster/6100

slave-serve-stale-data yes
slave-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
slave-priority 100
appendonly no
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
lua-time-limit 5000

 cluster-enabled yes
 
 cluster-config-file nodes-6100.conf
 
 cluster-node-timeout 15000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
aof-rewrite-incremental-fsync yes

保存退出

 复制配置文件到每个目录中

[root@C-06 ~]# cp redis.conf /redis_cluster/6100
[root@C-06 ~]# cp redis.conf /redis_cluster/6101
[root@C-06 ~]# cp redis.conf /redis_cluster/6102
[root@C-06 ~]# cp redis.conf /redis_cluster/6103
[root@C-06 ~]# cp redis.conf /redis_cluster/6104
[root@C-06 ~]# cp redis.conf /redis_cluster/6105
[root@C-06 ~]# yum -y install tree    #安装树状查看命令
[root@C-06 ~]# tree /redis_cluster/
/redis_cluster/
├── 6100
│   └── redis.conf
├── 6101
│   └── redis.conf
├── 6102
│   └── redis.conf
├── 6103
│   └── redis.conf
├── 6104
│   └── redis.conf
└── 6105
    └── redis.conf

6 directories, 6 files

 将6101目录中redis.conf 配置文件中所有的6100 替换成6101

[root@C-06 ~]# sed -i 's/6100/6101/g' /redis_cluster/6101/redis.conf
[root@C-06 ~]# sed -i 's/6100/6102/g' /redis_cluster/6102/redis.conf
[root@C-06 ~]# sed -i 's/6100/6103/g' /redis_cluster/6103/redis.conf
[root@C-06 ~]# sed -i 's/6100/6104/g' /redis_cluster/6104/redis.conf
[root@C-06 ~]# sed -i 's/6100/6105/g' /redis_cluster/6105/redis.conf

启动6个实例

[root@C-06 ~]# redis-server /redis_cluster/6100/redis.conf
[root@C-06 ~]# netstat -anput |grep redis
tcp        0      0 192.168.1.1:6100        0.0.0.0:*               LISTEN      19398/redis-server  

[root@C-06 ~]# redis-server /redis_cluster/6101/redis.conf
[root@C-06 ~]# redis-server /redis_cluster/6102/redis.conf
[root@C-06 ~]# redis-server /redis_cluster/6103/redis.conf
[root@C-06 ~]# redis-server /redis_cluster/6104/redis.conf
[root@C-06 ~]# redis-server /redis_cluster/6105/redis.conf

查看redis的进程和端口

[root@C-06 ~]# ps -ef | grep redis | grep cluster
root      19398      1  0 10:02 ?        00:00:00 redis-server 192.168.1.1:6100 [cluster]
root      19404      1  0 10:03 ?        00:00:00 redis-server 192.168.1.1:6101 [cluster]
root      19408      1  0 10:03 ?        00:00:00 redis-server 192.168.1.1:6102 [cluster]
root      19412      1  0 10:03 ?        00:00:00 redis-server 192.168.1.1:6103 [cluster]
root      19416      1  0 10:03 ?        00:00:00 redis-server 192.168.1.1:6104 [cluster]
root      19420      1  0 10:03 ?        00:00:00 redis-server 192.168.1.1:6105 [cluster]

[root@C-06 ~]# netstat -anput |grep redis
tcp        0      0 192.168.1.1:6100        0.0.0.0:*               LISTEN      19398/redis-server  
tcp        0      0 192.168.1.1:6101        0.0.0.0:*               LISTEN      19404/redis-server  
tcp        0      0 192.168.1.1:6102        0.0.0.0:*               LISTEN      19408/redis-server  
tcp        0      0 192.168.1.1:6103        0.0.0.0:*               LISTEN      19412/redis-server  
tcp        0      0 192.168.1.1:6104        0.0.0.0:*               LISTEN      19416/redis-server  
tcp        0      0 192.168.1.1:6105        0.0.0.0:*               LISTEN      19420/redis-server  
tcp        0      0 192.168.1.1:16100       0.0.0.0:*               LISTEN      19398/redis-server  
tcp        0      0 192.168.1.1:16101       0.0.0.0:*               LISTEN      19404/redis-server  
tcp        0      0 192.168.1.1:16102       0.0.0.0:*               LISTEN      19408/redis-server  
tcp        0      0 192.168.1.1:16103       0.0.0.0:*               LISTEN      19412/redis-server  
tcp        0      0 192.168.1.1:16104       0.0.0.0:*               LISTEN      19416/redis-server  
tcp        0      0 192.168.1.1:16105       0.0.0.0:*               LISTEN      19420/redis-server 

[root@C-06 ~]# tree /redis_cluster/
/redis_cluster/
├── 6100
│   ├── nodes-6100.conf
│   ├── redis_6100.log
│   └── redis.conf
├── 6101
│   ├── nodes-6101.conf
│   ├── redis_6101.log
│   └── redis.conf
├── 6102
│   ├── nodes-6102.conf
│   ├── redis_6102.log
│   └── redis.conf
├── 6103
│   ├── nodes-6103.conf
│   ├── redis_6103.log
│   └── redis.conf
├── 6104
│   ├── nodes-6104.conf
│   ├── redis_6104.log
│   └── redis.conf
├── 6105
│   ├── nodes-6105.conf
│   ├── redis_6105.log
│   └── redis.conf
├── redis_6100.pid
├── redis_6101.pid
├── redis_6102.pid
├── redis_6103.pid
├── redis_6104.pid
└── redis_6105.pid

2、使用脚本创建群集

创建群集要用到ruby的一个脚本,该脚本集成在redis的源码SRC目录下,需要系统安装配置ruby环境,才能使用该脚本进行Redis集群的创建、配置和管理

安装ruby工具:上传软件redis-3.2.0.gem

[root@C-06 ~]# yum -y install ruby rubygems
.........
....

[root@C-06 ~]# ll
-rw-r--r--  1 root root   71168 9月   8 10:21 redis-3.2.0.gem

[root@C-06 ~]# gem install redis --version 3.2.0
Successfully installed redis-3.2.0
Parsing documentation for redis-3.2.0
Installing ri documentation for redis-3.2.0
1 gem installed

[root@C-06 ~]# cd /usr/src/redis-3.2.9/src/

使用脚本安装redis群集

[root@C-06 src]# ./redis-trib.rb create --replicas 1 192.168.1.1:6100 192.168.1.1:6101 192.168.1.1:6102 192.168.1.1:6103 192.168.1.1:6104 192.168.1.1:6105
>>> Creating cluster
>>> Performing hash slots allocation on 6 nodes...
Using 3 masters:
192.168.1.1:6100
192.168.1.1:6101
192.168.1.1:6102
Adding replica 192.168.1.1:6103 to 192.168.1.1:6100
Adding replica 192.168.1.1:6104 to 192.168.1.1:6101
Adding replica 192.168.1.1:6105 to 192.168.1.1:6102
M: de4fed2e37c2bd0a2e4e3d2ce7db5de429721cb2 192.168.1.1:6100
   slots:0-5460 (5461 slots) master
M: 23003b7e7a5e02a067b1c43ce68ff05915710556 192.168.1.1:6101
   slots:5461-10922 (5462 slots) master
M: 412d11b1533b4860fa8d83ad4f989681afe4e4b0 192.168.1.1:6102
   slots:10923-16383 (5461 slots) master
S: 6b61c2c8c8e0baff2704c51f068ad7a9baf62e50 192.168.1.1:6103
   replicates de4fed2e37c2bd0a2e4e3d2ce7db5de429721cb2
S: 3c8dd7935dc54dccd40eb4d9e2f984a28e245692 192.168.1.1:6104
   replicates 23003b7e7a5e02a067b1c43ce68ff05915710556
S: 6a22c7dc961f0439789d204ddeda340bf86b98f3 192.168.1.1:6105
   replicates 412d11b1533b4860fa8d83ad4f989681afe4e4b0
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join.....
>>> Performing Cluster Check (using node 192.168.1.1:6100)
M: de4fed2e37c2bd0a2e4e3d2ce7db5de429721cb2 192.168.1.1:6100
   slots:0-5460 (5461 slots) master
   1 additional replica(s)
M: 23003b7e7a5e02a067b1c43ce68ff05915710556 192.168.1.1:6101
   slots:5461-10922 (5462 slots) master
   1 additional replica(s)
S: 6a22c7dc961f0439789d204ddeda340bf86b98f3 192.168.1.1:6105
   slots: (0 slots) slave
   replicates 412d11b1533b4860fa8d83ad4f989681afe4e4b0
M: 412d11b1533b4860fa8d83ad4f989681afe4e4b0 192.168.1.1:6102
   slots:10923-16383 (5461 slots) master
   1 additional replica(s)
S: 3c8dd7935dc54dccd40eb4d9e2f984a28e245692 192.168.1.1:6104
   slots: (0 slots) slave
   replicates 23003b7e7a5e02a067b1c43ce68ff05915710556
S: 6b61c2c8c8e0baff2704c51f068ad7a9baf62e50 192.168.1.1:6103
   slots: (0 slots) slave
   replicates de4fed2e37c2bd0a2e4e3d2ce7db5de429721cb2
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

查看集群状态

[root@C-06 src]# ./redis-trib.rb check 192.168.1.1:6100
>>> Performing Cluster Check (using node 192.168.1.1:6100)
M: de4fed2e37c2bd0a2e4e3d2ce7db5de429721cb2 192.168.1.1:6100
   slots:0-5460 (5461 slots) master
   1 additional replica(s)
M: 23003b7e7a5e02a067b1c43ce68ff05915710556 192.168.1.1:6101
   slots:5461-10922 (5462 slots) master
   1 additional replica(s)
S: 6a22c7dc961f0439789d204ddeda340bf86b98f3 192.168.1.1:6105
   slots: (0 slots) slave
   replicates 412d11b1533b4860fa8d83ad4f989681afe4e4b0
M: 412d11b1533b4860fa8d83ad4f989681afe4e4b0 192.168.1.1:6102
   slots:10923-16383 (5461 slots) master
   1 additional replica(s)
S: 3c8dd7935dc54dccd40eb4d9e2f984a28e245692 192.168.1.1:6104
   slots: (0 slots) slave
   replicates 23003b7e7a5e02a067b1c43ce68ff05915710556
S: 6b61c2c8c8e0baff2704c51f068ad7a9baf62e50 192.168.1.1:6103
   slots: (0 slots) slave
   replicates de4fed2e37c2bd0a2e4e3d2ce7db5de429721cb2
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

登录redis群集,设置键值测试

-h主机
-p端口
-c激活群集模式
[root@C-06 src]# redis-cli -h 192.168.1.1 -p 6100 -c
192.168.1.1:6100> set aaa 123
-> Redirected to slot [10439] located at 192.168.1.1:6101
OK
192.168.1.1:6101> quit 

[root@C-06 ~]# redis-cli -h 192.168.1.1 -p 6104 -c
192.168.1.1:6104> get aaa
-> Redirected to slot [10439] located at 192.168.1.1:6101
"123"

实验结果:登录集群的任意一个实例,当创建键值时,重定向到其他的服务器上,是按照slot分配的

复习题

1. 简述关系型数据库与非关系型数据库的区别,并分别列出对应的主流数据库

关系型数据库:关注在关系上

关系型主流数据库:Oracle、MySQL、SQL Server、Microsoft Access、DB2

非关系型数据库:关注在存储上

非关系型主流数据库:Redis、MongBD、Hbase、CouhDB

2. 简述Redis数据库具备的特点

特点:具有极高的数据读写速度、支持丰富的数据类型、支持数据的持久化、原子性、支持数据备份

3. 列出3个以上Redis常见应用场景

缓存、计数器、队列、分布式锁与单线程机制

4. 编译安装Redis时,若想更改默认的安装路径该执行什么命令?

made PREFIX=安装路径 install

5. 编译安装Redis时,执行install_server.sh脚本的作用是什么?

通过该脚本可以设置Redis服务所需要的相关配置文件

6. 写出3个以上优化Redis性能时所使用的参数

bind  ip

protected-mode yes

aof-rewrite-incremental-fsync yes

7. 执行redis-benchmark -c 100 -n 100000 命令的作用是什么?

向redis服务器发送100个并发连接与100000个请求

8. Redis集群节点使用哪两个端口?其作用分别是什么?

端口6379:服务于客户端的连接

端口16379:用于群集总线,即使用二进制协议的节点到节点通信通道

9. 执行gem install redis --version 3.2.0命令的作用是什么?

使用gem命令安装--version 3.2.0脚本

10. 部署Redis集群时所使用的集群创建脚本是哪个?

ruby脚本


版权声明:本文为KW__jiaoq原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。