概述
目录
- 一、什么是非关系型数据库
- (1)关系型数据库
- (2)非关系型数据库
- (3)非关系型数据库产生背景
- -High performance——对数据库高并发读写需求
- -Huge Storage——对海量数据高效存储与访问需求
- -High Scalability && High Availability——对数据库高可扩展性与高可用性需求
- -总结
- 二、Redis简介
- (1)优点
- (2)Redis的应用场景
- (3)搭建Redis数据库
- -主配置文件详解
- -redis主配置文件主要配置项
- -redis命令工具
- -命令行工具redis-cli
- -测试工具redis-benchmark
- -redis数据库常用命令
- -redis其他数据管理命令——keys
- -redis其他数据管理命令——exists
- -redis其他数据管理命令——del
- -redis其他数据管理命令——type
- -redis其他数据管理命令——rename
- -redis其他数据管理命令——renamenx
- -redis其他数据管理命令——dbsize
- -redis多数据常用命令
- 三、redis实战——搭建redis群集
- (1)redis群集原理
- (2)搭建redis群集
- (3)配置Ruby环境-redis-trib.rb脚本
- (4)测试
- (5)结论
- 四、扩展——trib.rb脚本的使用
一、什么是非关系型数据库
- 要理解什么是非关系型数据库,那么就不得不提到什么是关系型数据库
(1)关系型数据库
- 关系型数据库是一个结构化的数据库,创建在关系模型基础上,一般是面向于记录的,也叫SQL数据库,他的数据存放结构一般为:库——表——数据,例如:Oracle、Mysql、Sql Server、DB2这种都属于关系型数据库
(2)非关系型数据库
- 一般来说,除了主流的关系型数据库以外的数据库都被认为是非关系型的,非关系数据库也叫NoSQL数据库,从字面意思来看就是Not-Only SQL,这种数据库一般是作为SQL数据库的良好补充。
- 为什么要学习并且使用NoSQL数据库呢,因为随着互联网web2.0网站的兴起,NoSQL数据库已经成为了一个极其热门的领域,NoSQL数据库支持超大规模的数据存储,并且可以很好的支持web2.0网站和应用,正是因为如此,NoSQL数据库产品发展非常迅速,SQL数据库在应付web2.0网站特别是超大规模的高并发的SNS(社会性网络服务)类型的web2.0纯动态网站时,已经是力不从心了,从而暴露了SQL数据库很多难以克服的问题,这个时候就需要去使用NoSQL数据库去代替一些传统的SQL数据库。NoSQL数据库的数据存放结构常用的有:键值对(key-value)、列存储、文档、图形(graph)
- NoSQL数据库例如有:Redis、MongBD、Hbase、CouhDB等
(3)非关系型数据库产生背景
-High performance——对数据库高并发读写需求
web2.0网站要根据用户个性化信息来实时生成动态页面和提供动态信息,所以基本上无法使用动态页面静态化技术,因此数据库并发负载非常高,往往要达到每秒上万次读写请求。 关系数据库应付上万次SQL查询还勉强顶得住,但是应付上万次SQL写数据请求,硬盘IO就已经无法承受了。
其实对于普通的BBS网站,往往也存在对高并发写请求的需求,例如网站的实时统计在线用户状态,记录热门帖子的点击次数,投票计数等,因此这是一个相当普遍的需求。
-Huge Storage——对海量数据高效存储与访问需求
类似Facebook,twitter,Friendfeed这样的SNS网站,每天用户产生海量的用户动态,以Friendfeed为例,一个月就达到了2.5亿条用户动态, 对于关系数据库来说,在一张2.5亿条记录的表里面进行SQL查询,效率是极其低下乃至不可忍受的。
再例如大型web网站的用户登录系统,例如腾讯,盛大,动辄数以亿计的帐号,关系数据库也很难应付。
-High Scalability && High Availability——对数据库高可扩展性与高可用性需求
在基于web的架构当中,SQL数据库是最难进行横向扩展的
,当一个应用系统的用户量和访问量与日俱增的时候,你的数据库却没有办法像web server和app server那样简单的通过添加更多的硬件和服务节点来扩展性能和负载能力。对于很多需要提供24小时不间断服务的网站来说,对数据库系统进行升级和扩展是非常痛苦的事情,往往需要停机维护和数据迁移,为什么数据库不能通过不断的添加服务器节点来实现扩展呢?NoSQL的出现就是为了解决这一难题。
-总结
NoSQL数据库就是为了解决大规模数据集合多重数据种类带来的挑战,尤其是大数据应用难题而产生的。
本次讲述的就是采用键值对(key-value)存储形式的NoSQL数据库——Redis
二、Redis简介
- Redis基于内存运行并支持持久化,采用键值对(key-value)的存储形式
(1)优点
- 具有极高的数据读写速度
Redis是将数据存放到内存中,由于内存的存取速度快, 所以Redis被广泛应用在互联网项目中。
Redis官方称:Redis的读取速度会达到30万次每秒,写的速度在10万次每秒,具体局限主要看硬件 - 支持丰富的数据类型
Redis是用C语言开发的一个开源的高性能的键值对(key-value)数据库。
Redis通过提供多种键值数据类型来适应不同场景下的存储需求,目前为止,Redis支持的键值数据类型如下:
字符串类型、散列类型、列表类型、集合类型 - 支持数据的持久化
Redis可以将内存中的数据异步写入到硬盘中,同时不影响继续提供服务,但是Redis对持久化的支持不够好,所以一般来说Redis是配合传统的SQL数据库去使用的
- 原子性
Redis的所有操作都是原子性的(要么完整的执行,要么全不执行) - 支持数据备份
master/slave模式的数据备份(主从备份) - 功能丰富
Redis可以为每一个键设置生存时间,时间到期后该键被自动删除, 这一功能配合出色的性能让Redis可以作为缓存服务器来使用。而作为缓存服务器,Redis还可以限定数据占用的最大内存空间, 在数据达到空间限制后可以按照一定的规则自动淘汰不需要的键。Redis的列表类型键可以用来实现队列,并且支持阻塞式读取, 可以很容易的实现一个高性能的优先级队列。此外, Redis还支持“发布/订阅”的消息模式。
(2)Redis的应用场景
缓存、分布式集群架构中的session分离、聊天室的在线好友列表、任务队列、应用排行榜、网站访问统计、数据过期处理等。
(3)搭建Redis数据库
本实验使用cetnos7.*版本
******(1)先做基础配置
[root@centos7-007 ~]# hostnamectl set-hostname redis
[root@centos7-007 ~]# su
[root@redis ~]# systemctl stop firewalld
[root@redis ~]# setenforce 0
setenforce: SELinux is disabled
[root@redis ~]# mount /dev/cdrom /media/cdrom/
mount: /dev/sr0 写保护,将以只读方式挂载
******(2)上传redis源码包,解压、配置、编译、安装
[root@redis ~]# ll
总用量 1516
-rw-------. 1 root root 1220 9月 3 2020 anaconda-ks.cfg
-rw-r--r-- 1 root root 1547695 3月 7 06:01 redis-3.2.9.tar.gz
[root@redis ~]# tar xf redis-3.2.9.tar.gz -C /usr/src/
[root@redis ~]# cd /usr/src/redis-3.2.9/
[root@redis redis-3.2.9]# ls
00-RELEASENOTES INSTALL runtest tests
BUGS Makefile runtest-cluster utils
CONTRIBUTING MANIFESTO runtest-sentinel
COPYING README.md sentinel.conf
deps redis.conf src
[root@redis redis-3.2.9]# make && make install (我的这个源码包提供了makefile的文件,所以可以直接进行编译安装)
[root@redis redis-3.2.9]# cd utils/
[root@redis utils]# ls
build-static-symbols.tcl lru
cluster_fail_time.tcl redis-copy.rb
corrupt_rdb.c redis_init_script
create-cluster redis_init_script.tpl
generate-command-help.rb redis-sha1.rb
hashtable releasetools
hyperloglog speed-regression.tcl
install_server.sh whatisdoing.sh
[root@redis 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@redis utils]# /etc/init.d/redis_6379 start (启动redis)
Starting Redis server...
[root@redis utils]# netstat -anpt | grep redis (检查端口号,确认是否已经成功启动)
tcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN 4678/redis-server 1
[root@redis utils]# cd
******(3)可以通过脚本来管理redis的状态
[root@redis ~]# /etc/init.d/redis_6379 status
Redis is running (4678)
[root@redis ~]# /etc/init.d/redis_6379 stop
Stopping ...
Redis stopped
[root@redis ~]# /etc/init.d/redis_6379 start
Starting Redis server...
[root@redis ~]# /etc/init.d/redis_6379 status
Redis is running (4690)
******(4)编辑redis的主配置文件,绑定本地的ip地址
[root@redis ~]# vim /etc/redis/6379.conf (编辑主配置文件)
。。。。。。
61 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~
62 bind 127.0.0.1 192.168.100.7 (添加本机地址)
63
64 # Protected mode is a layer of security protection, in order to avoid that
。。。。。。
保存退出
******(5)重启redis
[root@redis ~]# /etc/init.d/redis_6379 restart (利用脚本重启redis)
Stopping ...
Redis stopped
Starting Redis server...
[root@redis ~]# netstat -anpt | grep redis (再次查看端口号)
tcp 0 0 192.168.100.7:6379 0.0.0.0:* LISTEN 4704/redis-server 1
tcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN 4704/redis-server 1
至此redis搭建完成!!!!
-主配置文件详解
******利用grep查看redis的主配置文件
[root@redis ~]# cat /etc/redis/6379.conf | grep -v "^#" | grep -v "^$"
bind 127.0.0.1 192.168.100.7 ——(监听的ip地址)
protected-mode yes ——(是否开启保护模式,默认是开启的,如果已经指定bind和密码那么只会在本地进行访问而拒绝外部访问,如果没有指定bind和密码那么这个选项最好关闭)
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 ——(redis进程的pi文件)
loglevel notice ——(指定了服务端日志的级别,即:notice表示适当的日志级别适合生产环境,debug表示很多信息方便开发和测试,verbose表示许多有用的信息但是没有debug的信息多,warn表示只有非常重要的信息)
logfile /var/log/redis_6379.log ——(指定了redis记录日志的文件)
databases 16 ——(数据库的数量,默认使用的数据库是DB0)
save 900 1 ——(save项是数据持久化配置,将内存中的数据写入到数据库中,900 1即表示900秒内只要发生1个key值的变化就进行数据保存)
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes ——(当RDB持久化出现错误后是否依然进行工作)
rdbcompression yes ——(是否使用压缩rdb文件,rdb文件压缩使用LZF压缩算法,即:yes表示使用压缩但是会消耗一定的cpu资源,no表示不压缩但是需要更多的存储空间)
rdbchecksum yes ——(是否校验rdb文件,开启这个项会有%10的性能损耗但是更有利于rdb文件的容错性,如果追求高性能建议关闭)
dbfilename dump.rdb ——(指定rdb文件的名称)
dir /var/lib/redis/6379 ——(指定数据目录,数据库的写入、rdb文件、aof文件都会写在这个目录)
slave-serve-stale-data yes ——(在从库和主机失去连接或者复制正在进行时,从机库有两种运行方式,即:yes表示从库会继续响应客户端的请求,no表示出去INFO和SLAVOF命令之外的任何请求都会返回错误信息”SYNC with master in progress”)
slave-read-only yes ——(作为从服务器,yes表示只读也是默认的,no用于写但是不建议修改)
repl-diskless-sync no ——(是否使用socket方式复制数据,在磁盘速度缓慢,网速快的情况下推荐使用)
repl-diskless-sync-delay 5 ——(指定diskless复制的延迟时间,防止设置为0,一旦复制开始,节点不会再接收新的slave的复制请求,直到下一个rdb传输,所以最好等待一段时间,等待更多的slave连上来)
repl-disable-tcp-nodelay no ——(是否禁止复制tcp链接的tcp nodelay参数,默认是no,即使用tcp nodelay参数,如果选择yes那么在把数据复制给slave的时候,会减少包的数量和更小的网络宽带,可能会带来数据延迟,所以默认选择低延迟,在数据量传输很大的场景下推荐使用yes)
slave-priority 100 ——(指定slave的优先级,当master不可用时,Sentinel会根据slave优先级选举master,最低的优先级选举为master,如果配置成0则永远不会被选举)
appendonly no ——(是否使用append only file的持久化方式,redis默认使用的持久化方式是rdb,这种方式在许多应用中已经足够了,但是在服务器宕机时还是会操作几分钟的数据丢失,并且rdb根据save来策略进行持久化,而append only file提供更好的持久化方式,但是开启后redis每次都会先把appendonly.aof文件存入内存,会忽略rdb文件)
appendfilename "appendonly.aof" ——(指定aof文件名)
appendfsync everysec ——(指定aof持久化策略,everysec表示每秒执行一次同步,可能会丢失这1秒的数据,always表示每次写入都执行一次同步,no则表示不执行同步,由操作系统保证数据同步到磁盘,速度最快)
no-appendfsync-on-rewrite no ——(配置是否不在rewrite期间对新写操作不进行同步,对延迟要求很高的应用,可以配置为yes,为yes即表示在rewrite完成后在进行写入,默认为no,但是linux默认策略是30秒进行同步,可能会丢失30秒的数据所以建议选择yes)
auto-aof-rewrite-percentage 100 ——(aof自动重写配置,当前aof文件大小是上次日志重写得到aof文件大小的两倍(设置为100时),会自动启动新的日志重写过程)
auto-aof-rewrite-min-size 64mb ——(设置运行重写的最小aof文件的大小,此项可以避免达到约定百分比但是尺寸依然很小的情况下还要重写)
aof-load-truncated yes ——(选择yes则表示截断的aof文件被导入时,会自动发布一个log日志给客户端然后load保存,如果是no则表示用户必需手动输入redis-check-aof修复aof文件才可以)
lua-time-limit 5000 ——(配置最大时间限制,当达到最大时间redis会记个log日志,然后返回error错误)
slowlog-log-slower-than 10000 ——(slowlog用来记录redis运行中执行比较慢的命令耗时,当命令的执行超过配置的时间,就会记录在slow log中,slow log保存在内存里,所以没有I/O操作。注意:这个单位是微秒即1000000微妙 = 1秒)
slowlog-max-len 128 ——(指定慢查询日志的长度,当一个新的命令被写进日志的时候最老的记录会被删除,这个长度没有限制,只要有足够的内存就行,也可以通过SLOWLOG RESET 来释放内存)
latency-monitor-threshold 0 ——(是否开启延迟监控功能,延迟监控功能是用来监控redis中执行比较缓慢的一些操作,设置为0则表示关闭监视,默认情况是关闭的,可以使用CONFIG SET命令动态设置)
notify-keyspace-events "" ——(是否开启键空间通知,键空间通知使得客户端可以通过订阅频道或模式,来接受那些以某种方式改动了redis数据集的事件,默认情况下是关闭的)
hash-max-ziplist-entries 512 ——(当数据量小于等于指定值的使用ziplist,大于指定值使用hash)
hash-max-ziplist-value 64 ——(value大小小于等于指定值的使用ziplist,大于指定值使用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 ——(开启这个选项redis将在每100毫秒时使用1毫秒的cpu时间来对redis的hash表进行重新hash,可以降低内存的使用,如果你有非常严格的实时性要求的话,可以把此项关闭no)
client-output-buffer-limit normal 0 0 0 ——(这个选项可以对客户端输出缓冲进行限制可以强迫那些不是从服务器读取数据的客户端断开连接,用来强制关闭传输缓慢的客户端,第一个0表示取消hard limit第二个和第三个0表示取消soft limit,normal client默认取消限制)
client-output-buffer-limit slave 256mb 64mb 60 ——(对于slave,当client-output-buffer(客户端的输出缓存区)一旦超过256mb或者超过64mb并且持续60秒,那么服务器会立即断开客户端连接)
client-output-buffer-limit pubsub 32mb 8mb 60 ——(对于pubsub,当client-output-buffer一旦超过32mb或者超过8mb并且持续60秒,那么服务器会立即断开客户端链接)
hz 10 ——(redis执行任务的频率为1秒除以hz的值)
aof-rewrite-incremental-fsync yes ——(当选择yes时,在aof重写的时候,系统会每32mb执行一次fsync同步,对于把文件写入磁盘是有帮助的,可以避免过大的延迟峰值)
-redis主配置文件主要配置项
(1)bind:监听的主机地址
(2)port:端口
(3)daemonize yes:启动守护进程
(4)pidfile:指定的pid文件
(5)loglevel notice:日志级别
(6)logfile:指定日志文件
-redis命令工具
******redis的命令工具放在了/usr/local/bin/下,其中以reids开头的都为redis的命令工具
[root@redis ~]# ls /usr/local/bin/
redis-benchmark redis-check-rdb redis-sentinel
redis-check-aof redis-cli redis-server
******命令工具解析:
redis-benchmark 用于检测redis在本机的运行效率,即服务的性能
redis-check-rdb 修复RDB持久化文件
redis-sentinel redis-server的软连接
redis-check-aof 修复AOF持久化文件
redis-cli redis命令行工具
redis-server 用于启动redis的工具
-命令行工具redis-cli
******连接本机的redis数据库
[root@redis ~]# redis-cli (连接本机数据库)
127.0.0.1:6379> ping (检测redis是否启动返回PONG则说明已经启动)
PONG
127.0.0.1:6379> exit
[root@redis ~]#
******远程访问redis数据库
-h 指定远程主机 -p 指定服务端口 -a 用户密码
[root@redis ~]# redis-cli -h 192.168.100.7 -p 6379
192.168.100.7:6379>
******在数据库环境下获取命令帮助:
help @<group>:获取<group>中的命令列表
help <command>:获取某个命令的帮助
help <tab>:获取可能帮助的主题列表
192.168.100.7:6379> info (查看服务的统计信息)
192.168.100.7:6379> help @list (查看所有与list数据类型相关的命令)
192.168.100.7:6379> help set (查看set命令的帮助信息)
-测试工具redis-benchmark
******redis-benchmark测试工具可以模拟n个客户端发出m个请求,类似于apache ab程序,从而测试服务性能
语法:redis-benchmark [-h <host>][-p ] [-c <clients>][-n ]> [-k <boolean>]
******选项:
-h <hostname> 主机名 (默认 127.0.0.1)
-p <port> 主机端口 (默认 6379)
-s <socket> UNIX socket (会覆盖 -h -p 设置的内容)
-a <password> 密码(密码错误之类的不会直接保错,而是在操作时才会保错,这时可以使用 Redis 的 AUTH 命令再次认证)
-c <clients> 客户端的并发数量(默认是50)
-n <requests> 客户端请求总量(默认是100000)
-d <size> 使用 SET/GET 添加的数据的字节大小 (默认 2)
-dbnum <db> 选择一个数据库进行测试 (默认 0)
-k <boolean> 客户端是否使用keepalive,1为使用,0为不使用,(默认为 1)
-r <keyspacelen> 使用 SET/GET/INCR 命令添加数据 key, SADD 添加随机数据,keyspacelen 指定的是添加 键的数量
-P <numreq> 每个请求 pipeline 的数据量(默认为1,没有 pipeline )
-q 仅仅显示redis-benchmark的requests per second信息
--csv 将结果按照csv格式输出,便于后续处理
-l 循环测试
-t <tests> 可以对指定命令进行基准测试
-I 空闲模式 只打开N个空闲连接并等待。
******例:向redis服务器发送100个并发连接与100000个请求
[root@redis ~]# redis-benchmark -h 192.168.100.7 -p 6379 -c 100 -n 100000
====== PING_INLINE ======
100000 requests completed in 1.13 seconds
100 parallel clients
3 bytes payload
keep alive: 1
。。。。。。。。。。。(中间省略)
====== MSET (10 keys) ====== (汇总信息)
100000 requests completed in 1.27 seconds (表示十万个请求包在1.27秒完成)
100 parallel clients (100个并发连接统计)
3 bytes payload
keep alive: 1
60.54% <= 1 milliseconds (milliseconds表示毫秒)
99.99% <= 2 milliseconds
100.00% <= 2 milliseconds
78678.20 requests per second (每秒可以处理78678.20个请求)
******例:测试存取大小为100b的数据包的性能
[root@redis ~]# redis-benchmark -h 192.168.100.7 -p 6379 -q -d 100PING_INLINE: 96899.23 requests per second
PING_BULK: 97943.19 requests per second
SET: 94607.38 requests per second
GET: 95328.88 requests per second
INCR: 96525.09 requests per second
LPUSH: 92336.11 requests per second
RPUSH: 73691.97 requests per second
LPOP: 91996.32 requests per second
RPOP: 91911.76 requests per second
SADD: 94786.73 requests per second
SPOP: 96246.39 requests per second
LPUSH (needed to benchmark LRANGE): 91575.09 requests per second
LRANGE_100 (first 100 elements): 42283.30 requests per second
LRANGE_300 (first 300 elements): 13468.01 requests per second
LRANGE_500 (first 450 elements): 7964.32 requests per second
LRANGE_600 (first 600 elements): 5575.07 requests per second
MSET (10 keys): 75757.57 requests per second (表示每秒75757.57个请求)
******例:测试本机上redis服务在进行set和lpush操作时的性能
[root@redis ~]# redis-benchmark -t set,lpush -n 100000 -q
SET: 65832.78 requests per second (在进行set操作时每秒65832.78个请求)
LPUSH: 93984.96 requests per second (在进行lpush操作时每秒93984.96个请求)
-redis数据库常用命令
******常用存放、获取命令
(1)set:存放数据
(2)get:获取数据
(3)key的相关命令:
keys、exists、del、type、rename、renamenx、dbsize
(4)key-value键值对的数据存储形式:
set :set key value
get :get key
[root@redis ~]# redis-cli (进入数据库)
127.0.0.1:6379> set aaa ly (存放一个键名为aaa值为ly的数据)
OK
127.0.0.1:6379> get aaa (获取键名为aaa的值)
"ly"
127.0.0.1:6379>
-redis其他数据管理命令——keys
******key相关命令
keys——获取符合规则的键值列表(*?)
*——表示任意字符
?——表示一个字符
[root@redis ~]# redis-cli (创建多个键值)
127.0.0.1:6379> set a1 1
OK
127.0.0.1:6379> set a2 2
OK
127.0.0.1:6379> set a3 3
OK
127.0.0.1:6379> set a4 4
OK
127.0.0.1:6379> set a5 5
OK
127.0.0.1:6379> keys * (查看所有键)
1) "a4"
2) "a5"
3) "mylist"
4) "a2"
5) "a1"
6) "key:__rand_int__"
7) "aaa"
8) "a3"
9) "counter:__rand_int__"
127.0.0.1:6379> set b1 1 (创建一个以b开头的键)
OK
127.0.0.1:6379> keys b* (查看以b开头的键)
1) "b1"
127.0.0.1:6379> set b222 222 (创建一个新的键)
OK
127.0.0.1:6379> keys b? (查看以b开头的后面任意一个字符的键)
1) "b1"
127.0.0.1:6379> keys b??? (查看以b开头的后面任意三个字符的键)
1) "b222"
-redis其他数据管理命令——exists
******exists——判断键值是否存在
integer——返回值1表示存在,0表示不存在
[root@redis ~]# redis-cli
127.0.0.1:6379> EXISTS aaa (判断aaa键值是否存在)
(integer) 1 (返回1说明存在)
127.0.0.1:6379> EXISTS bbb
(integer) 0 (返回0说明不存在)
127.0.0.1:6379> keys * (查看所有键值,确认bbb是不存在的,aaa存在)
1) "a4"
2) "a5"
3) "mylist"
4) "a2"
5) "b222"
6) "a1"
7) "key:__rand_int__"
8) "aaa"
9) "a3"
10) "b1"
11) "counter:__rand_int__"
-redis其他数据管理命令——del
******del——删除当前数据库的指定键值
[root@redis ~]# redis-cli
127.0.0.1:6379> keys * (先查看所有键值)
1) "a4"
2) "a5"
3) "mylist"
4) "a2"
5) "b222"
6) "a1"
7) "key:__rand_int__"
8) "aaa"
9) "a3"
10) "b1"
11) "counter:__rand_int__"
127.0.0.1:6379> del aaa (删除aaa这个键值)
(integer) 1
127.0.0.1:6379> get aaa (使用get查看aaa键的值发现无法查看)
(nil)
127.0.0.1:6379> keys * (再次查看所有键值发现aaa键值已经没了)
1) "a4"
2) "a5"
3) "mylist"
4) "a2"
5) "b222"
6) "a1"
7) "key:__rand_int__"
8) "a3"
9) "b1"
10) "counter:__rand_int__"
-redis其他数据管理命令——type
******type——获取键对应的值的类型
[root@redis ~]# redis-cli
127.0.0.1:6379> keys * (查看所有键值)
1) "a4"
2) "a5"
3) "mylist"
4) "a2"
5) "b222"
6) "a1"
7) "key:__rand_int__"
8) "a3"
9) "b1"
10) "counter:__rand_int__"
127.0.0.1:6379> TYPE a1 (查看a1键值的类型)
string (string表示字符串类型)
-redis其他数据管理命令——rename
******rename——重命名
rename 源键 目标键
——————————————————————————————————————注意——————————————————————————————————————
使用rename会直接覆盖目标键,无论是否存在,即不管有没有数据都会被最后输入的新键名覆盖,就是说就算有了这个键命,也会被刚刚输入的新键名覆盖。
在真实环境中一定要先使用exists先查看目标是否存在然后在决定是否使用rename
————————————————————————————————————————————————————————————————————————————————
[root@redis ~]# redis-cli
127.0.0.1:6379> keys * (查看所有的键值)
1) "a4"
2) "a5"
3) "mylist"
4) "a2"
5) "b222"
6) "a1"
7) "key:__rand_int__"
8) "a3"
9) "b1"
10) "counter:__rand_int__"
127.0.0.1:6379> get a4 (查看a4的值)
"4"
127.0.0.1:6379> rename a4 b4 (重命名a4为b4)
OK
127.0.0.1:6379> keys * (再次查看所有的键发现没有a4,但是有b4)
1) "a5"
2) "mylist"
3) "a2"
4) "b222"
5) "a1"
6) "key:__rand_int__"
7) "b4"
8) "a3"
9) "b1"
10) "counter:__rand_int__"
127.0.0.1:6379> get b4 (查看b4的值,发现被a4的值覆盖了)
"4"
127.0.0.1:6379> get a4 (查看a4的值,发现无法查询)
(nil)
127.0.0.1:6379> get a1 (查看a1键的值)
"1"
127.0.0.1:6379> get a2 (查看a2键的值)
"2"
127.0.0.1:6379> rename a1 a2 (修改a1键名为a2)
OK
127.0.0.1:6379> get a2 (查看a2的值发现呗原来a1的值覆盖了)
"1"
127.0.0.1:6379> get a1 (查看a1的值发现无法查询)
(nil)
-redis其他数据管理命令——renamenx
******renamenx——对已有键进行重命名,并且检测新的名称是否存在,如果新的名称存在,那么则不进行重命名,在真实环境中推荐使用,避免了rename错误覆盖键值
renamenx 源键 目标键 (返回1为成功,0为失败)
[root@redis ~]# redis-cli
127.0.0.1:6379> keys * (查看所有键值)
1) "a5"
2) "mylist"
3) "a2"
4) "b222"
5) "key:__rand_int__"
6) "b4"
7) "a3"
8) "b1"
9) "counter:__rand_int__"
127.0.0.1:6379> RENAMENX a5 a6 (把a5键名改为a6)
(integer) 1 (返回1表示修改成功)
127.0.0.1:6379> renamenx a2 b1 (把a2键名改为b1)
(integer) 0 (返回0表示修改失败)
127.0.0.1:6379> keys * (再次查看所有键值,发现没有了a5,多了a6,a2存在,b1也存在)
1) "mylist"
2) "a2"
3) "b222"
4) "key:__rand_int__"
5) "a6"
6) "b4"
7) "a3"
8) "b1"
9) "counter:__rand_int__"
-redis其他数据管理命令——dbsize
******dbsize——查看当前数据库中键的数量
[root@redis ~]# redis-cli
127.0.0.1:6379> dbsize (查看数据库中所有键的数量)
(integer) 9
127.0.0.1:6379> keys * (查看所有键值发现有9个)
1) "mylist"
2) "a2"
3) "b222"
4) "key:__rand_int__"
5) "a6"
6) "b4"
7) "a3"
8) "b1"
9) "counter:__rand_int__"
-redis多数据常用命令
******redis默认的数据库有16个即0——15,即使用db 0 —— db 15来表示,默认连接的数据库为db 0
(1)select 数据库序号 ————切换到指定数据库
[root@redis ~]# redis-cli
127.0.0.1:6379> SELECT 10 (切换到10号数据库)
OK
127.0.0.1:6379[10]> SELECT 15 (切换到15号数据库)
OK
127.0.0.1:6379[15]> SELECT 0 (切换到0号数据库)
OK
127.0.0.1:6379>
(2)move 键名 数据库序号 ————移动当前数据库的指定键值到指定的数据库,返回1表示成功,返回0表示失败。
————————————————————————————注意——————————————————————————
如果移动的键名在目标数据库中存在,那么是无法移动成功的
——————————————————————————————————————————————————————————
[root@redis ~]# redis-cli
127.0.0.1:6379> select 15 (切换到15号数据库)
OK
127.0.0.1:6379[15]> keys * (查看当前数据库的所有键值,发现没有任何键值)
(empty list or set)
127.0.0.1:6379[15]> set aaa 1 (创建一个键名为aaa值为1的键值)
OK
127.0.0.1:6379[15]> keys * (查看所有键值)
1) "aaa"
127.0.0.1:6379[15]> move aaa 10 (移动aaa这个键到10号数据库)
(integer) 1 (返回1说明移动成功)
127.0.0.1:6379[15]> keys * (再次查看当前数据的所有键值,发现没有任何键值)
(empty list or set)
127.0.0.1:6379[15]> select 10 (切换到10号数据库)
OK
127.0.0.1:6379[10]> keys * (查看当前数据库所有键值,发现多了aaa键)
1) "aaa"
127.0.0.1:6379[10]> SELECT 5 (切换到5号数据库)
OK
127.0.0.1:6379[5]> set aaa 1 (创建名为aaa的键值为1)
OK
127.0.0.1:6379[5]> move aaa 10 (移动aaa键值到10号库)
(integer) 0 (返回0说明移动失败)
127.0.0.1:6379[5]> keys * (查看当前数据库的所有键,发现有一个aaa键值)
1) "aaa"
(3)flushdb ————清除当前数据库内所有数据
————————————————————————注意————————————————————————
执行flushdb会清空当前数据库的所有数据要谨慎使用
————————————————————————————————————————————————————
[root@redis ~]# redis-cli
127.0.0.1:6379> select 10 (切换到10号数据库)
OK
127.0.0.1:6379[10]> keys * (查看所有键值)
1) "aaa"
127.0.0.1:6379[10]> flushdb (清除当前数据库内所有数据)
OK
127.0.0.1:6379[10]> keys * (再次查看所有键值,发现什么都没有了)
(empty list or set)
三、redis实战——搭建redis群集
(1)redis群集原理
- redis群集架构:
redis 群集采用虚拟槽分区,将所有的数据根据算法映射到0~16383整数槽中,并且是一个无中心的结构,每个节点都保存数据和整个群集的状态 - 群集角色
Master:Master之间分配虚拟槽slots
Slave:Slave向它指向的Master同步数据 - 群集节点使用的TCP端口
6379端口用于客户端的连接,16379端口用于群集总线
(2)搭建redis群集
为了节省资源,本次实验在单台服务器上搭建redis群集,通过不同的TCP端口去启动多个实例,模拟多台独立的redis服务器组成的群集
注意:至少需要六个实例也就是六个redis服务器才能组成群集,3主3从会自动分配
******本次实验思路为:在根目录下创建一个新目录,用于存放多实例配置文件,即使用多个redis主配置文件,但是每台实例的端口都不同,使用这六个主配置文件启动实例,并且搭建redis群集
******(1)首先先关闭redis服务器
[root@redis ~]# /etc/init.d/redis_6379 stop (关闭redis)
Stopping ...
Redis stopped
[root@redis ~]# netstat -anpt | grep redis (检查是否成功关闭)
******(2)创建新的群集目录,并且分别创建不同的redis目录
[root@redis ~]# mkdir -p /redis/{6001..6006} (这里利用6001——6006来区分多态实例)
[root@redis ~]# ll /redis/
总用量 0
drwxr-xr-x 2 root root 6 3月 8 01:42 6001
drwxr-xr-x 2 root root 6 3月 8 01:42 6002
drwxr-xr-x 2 root root 6 3月 8 01:42 6003
drwxr-xr-x 2 root root 6 3月 8 01:42 6004
drwxr-xr-x 2 root root 6 3月 8 01:42 6005
drwxr-xr-x 2 root root 6 3月 8 01:42 6006
******(3)复制多个主配置文件
[root@redis ~]# cat /usr/src/redis-3.2.9/redis.conf | grep -v "^#"| grep -v "^$" > redis.conf (先保存一份当家目录)
[root@redis ~]# vim redis.conf (修改为:也可以之间复制,修改的行分别为1、3、7、9、11、20、35、36、37)
bind 192.168.100.7 #根据实际情况去修改ip地址,群集节点间必须可以进行正常通信,网络层面需要开启相应端口的访问权限
protected-mode yes
port 6001 #修改端口号
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize yes #运行redis在后台运行
supervised no
pidfile /var/run/redis_6001.pid #修改pid文件,每个实例都要修改成指定的
loglevel notice
logfile "/redis/6001/redis_6001.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/6001 #每个实例要修改成对应的目录
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-6001.conf #群集配置文件,每个实例都要有相对应的配置文件
cluster-node-timeout 15000 #请求超时时长,默认15秒,根据实际情况修改
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@redis ~]# cp redis.conf /redis/6001(依次复制文件到各个实例的目录)
[root@redis ~]# cp redis.conf /redis/6002
[root@redis ~]# cp redis.conf /redis/6003
[root@redis ~]# cp redis.conf /redis/6004
[root@redis ~]# cp redis.conf /redis/6005
[root@redis ~]# cp redis.conf /redis/6006
[root@redis ~]# sed -i 's/6001/6002/g' /redis/6002/redis.conf (使用sed替换配置文件中的6001为各个实例的端口号)
[root@redis ~]# sed -i 's/6001/6003/g' /redis/6003/redis.conf
[root@redis ~]# sed -i 's/6001/6004/g' /redis/6004/redis.conf
[root@redis ~]# sed -i 's/6001/6005/g' /redis/6005/redis.conf
[root@redis ~]# sed -i 's/6001/6006/g' /redis/6006/redis.conf
******(4)启动各个实例
[root@redis ~]# redis-server /redis/6001/redis.conf (依次使用redis-server启动各个实例)
[root@redis ~]# redis-server /redis/6002/redis.conf
[root@redis ~]# redis-server /redis/6003/redis.conf
[root@redis ~]# redis-server /redis/6004/redis.conf
[root@redis ~]# redis-server /redis/6005/redis.conf
[root@redis ~]# redis-server /redis/6006/redis.conf
[root@redis ~]# netstat -anpt | grep redis (检查端口,确定各个实例都已经正常启动)
tcp 0 0 192.168.100.7:6001 0.0.0.0:* LISTEN 1461/redis-server 1
tcp 0 0 192.168.100.7:6002 0.0.0.0:* LISTEN 1465/redis-server 1
tcp 0 0 192.168.100.7:6003 0.0.0.0:* LISTEN 1470/redis-server 1
tcp 0 0 192.168.100.7:6004 0.0.0.0:* LISTEN 1474/redis-server 1
tcp 0 0 192.168.100.7:6005 0.0.0.0:* LISTEN 1478/redis-server 1
tcp 0 0 192.168.100.7:6006 0.0.0.0:* LISTEN 1482/redis-server 1
tcp 0 0 192.168.100.7:16001 0.0.0.0:* LISTEN 1461/redis-server 1
tcp 0 0 192.168.100.7:16002 0.0.0.0:* LISTEN 1465/redis-server 1
tcp 0 0 192.168.100.7:16003 0.0.0.0:* LISTEN 1470/redis-server 1
tcp 0 0 192.168.100.7:16004 0.0.0.0:* LISTEN 1474/redis-server 1
tcp 0 0 192.168.100.7:16005 0.0.0.0:* LISTEN 1478/redis-server 1
tcp 0 0 192.168.100.7:16006 0.0.0.0:* LISTEN 1482/redis-server 1
至此redis群集搭建完成!!!
(3)配置Ruby环境-redis-trib.rb脚本
因为redis3.0之后开始支持群集功能,官方退出了一个管理集群的工具,一个Ruby脚本————redis-trib.rb
该脚本集成在redis的源码SRC目录下,所以需要系统安装配置ruby环境,才可以使用该脚本进行redis群集的创建、配置和管理。
******(1)安装ruby工具
[root@redis ~]# yum -y install ruby rubygems
。。。。。。
完毕!
******(2)上传文件,使用脚本安装redis群集
[root@redis ~]# ll
总用量 1596
-rw-------. 1 root root 1220 9月 3 2020 anaconda-ks.cfg
-rw-r--r-- 1 root root 76 3月 8 01:50 dump.rdb
-rw-r--r-- 1 root root 71168 3月 8 02:20 redis-3.2.0.gem
-rw-r--r-- 1 root root 1547695 3月 7 06:01 redis-3.2.9.tar.gz
-rw-r--r-- 1 root root 1293 3月 8 01:57 redis.conf
[root@redis ~]# 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@redis ~]# cd /usr/src/redis-3.2.9/src/ (安装完成后会发现/usr/src下多了一个redis目录)
[root@redis src]# ./redis-trib.rb create --replicas 1 192.168.100.7:6001 192.168.100.7:6002 192.168.100.7:6003 192.168.100.7:6004 192.168.100.7:6005 192.168.100.7:6006 (使用脚本安装redis群集,1就是nodeid号)
>>> Creating cluster
>>> Performing hash slots allocation on 6 nodes...
Using 3 masters:
192.168.100.7:6001
192.168.100.7:6002
192.168.100.7:6003
Adding replica 192.168.100.7:6004 to 192.168.100.7:6001
Adding replica 192.168.100.7:6005 to 192.168.100.7:6002
Adding replica 192.168.100.7:6006 to 192.168.100.7:6003
M: 86e8a7f5a7c6aa465ee8d20b8a9be340f2fc51b7 192.168.100.7:6001
slots:0-5460 (5461 slots) master
M: 536694c3cb5084ca424fd8c5f7b39591e5f7dac0 192.168.100.7:6002
slots:5461-10922 (5462 slots) master
M: c3df16a5c876eca9dc4b409e1a17fa7295c0f88d 192.168.100.7:6003
slots:10923-16383 (5461 slots) master
S: c3b870daf4dc533c8483b40ea08dde38def5f753 192.168.100.7:6004
replicates 86e8a7f5a7c6aa465ee8d20b8a9be340f2fc51b7
S: 065d7fbb560dd8cda9a493400eda463bdb1e2e97 192.168.100.7:6005
replicates 536694c3cb5084ca424fd8c5f7b39591e5f7dac0
S: 3d3d404951283622d56ae045350a04d831825782 192.168.100.7:6006
replicates c3df16a5c876eca9dc4b409e1a17fa7295c0f88d
Can I set the above configuration? (type 'yes' to accept): yes (输入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.100.7:6001)
M: 86e8a7f5a7c6aa465ee8d20b8a9be340f2fc51b7 192.168.100.7:6001
slots:0-5460 (5461 slots) master
1 additional replica(s)
S: c3b870daf4dc533c8483b40ea08dde38def5f753 192.168.100.7:6004
slots: (0 slots) slave
replicates 86e8a7f5a7c6aa465ee8d20b8a9be340f2fc51b7
S: 065d7fbb560dd8cda9a493400eda463bdb1e2e97 192.168.100.7:6005
slots: (0 slots) slave
replicates 536694c3cb5084ca424fd8c5f7b39591e5f7dac0
M: 536694c3cb5084ca424fd8c5f7b39591e5f7dac0 192.168.100.7:6002
slots:5461-10922 (5462 slots) master
1 additional replica(s)
M: c3df16a5c876eca9dc4b409e1a17fa7295c0f88d 192.168.100.7:6003
slots:10923-16383 (5461 slots) master
1 additional replica(s)
S: 3d3d404951283622d56ae045350a04d831825782 192.168.100.7:6006
slots: (0 slots) slave
replicates c3df16a5c876eca9dc4b409e1a17fa7295c0f88d
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
******(3)查看群集状态
[root@redis src]# ./redis-trib.rb check 192.168.100.7:6001 (查看群集状态)
>>> Performing Cluster Check (using node 192.168.100.7:6001)
M: 86e8a7f5a7c6aa465ee8d20b8a9be340f2fc51b7 192.168.100.7:6001
slots:0-5460 (5461 slots) master
1 additional replica(s)
S: c3b870daf4dc533c8483b40ea08dde38def5f753 192.168.100.7:6004
slots: (0 slots) slave
replicates 86e8a7f5a7c6aa465ee8d20b8a9be340f2fc51b7
S: 065d7fbb560dd8cda9a493400eda463bdb1e2e97 192.168.100.7:6005
slots: (0 slots) slave
replicates 536694c3cb5084ca424fd8c5f7b39591e5f7dac0
M: 536694c3cb5084ca424fd8c5f7b39591e5f7dac0 192.168.100.7:6002
slots:5461-10922 (5462 slots) master
1 additional replica(s)
M: c3df16a5c876eca9dc4b409e1a17fa7295c0f88d 192.168.100.7:6003
slots:10923-16383 (5461 slots) master
1 additional replica(s)
S: 3d3d404951283622d56ae045350a04d831825782 192.168.100.7:6006
slots: (0 slots) slave
replicates c3df16a5c876eca9dc4b409e1a17fa7295c0f88d
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
(4)测试
******(1)登录redis群集,进行键值测试
-h:主机
-p:端口
-c:激活群集模式
[root@redis src]# redis-cli -h 192.168.100.7 -p 6001 -c
192.168.100.7:6001> set aaa 111
-> Redirected to slot [10439] located at 192.168.100.7:6002
OK
192.168.100.7:6002> get aaa
"111"
192.168.100.7:6002> exit
(5)结论
通过这次实验我们可以得知,登录群集的任意一个实例创建键值时,会重定向到其他的服务器上,是按照slot槽点进行分配的
四、扩展——trib.rb脚本的使用
[root@redis ~]# cd /usr/src/redis-3.2.9/src/
[root@redis src]# ./redis-trib.rb help (下列选项使用格式为./redis-trib.rb 选项)
Usage: redis-trib <command> <options> <arguments ...>
create host1:port1 ... hostN:portN ——(创建群集,格式为 主机地址:端口号)
--replicas <arg> ——(replicas参数指定当前创建的redis群集有几个slave节点)
check host:port ——(检查群集,验证节点是否可用,格式为: 主机地址:端口号)
info host:port ——(查看群集信息,节点信息,格式为: 主机地址:端口号)
fix host:port ——(修复群集,格式为: 主机地址:端口号)
--timeout <arg>
reshard host:port ——(在线迁移群集,格式为: form 主机地址:端口号 to 主机地址:端口号 )
--from <arg>
--to <arg>
--slots <arg>
--yes
--timeout <arg>
--pipeline <arg>
rebalance host:port ——(平衡群集节点的槽点数量,格式为: 主机地址:端口号)
--weight <arg>
--auto-weights
--use-empty-masters
--timeout <arg>
--simulate
--pipeline <arg>
--threshold <arg>
add-node new_host:new_port existing_host:existing_port ——(在线添加新的群集节点,格式为: 新的主机地址:新的端口号 现有的主机地址:现有的端口号)
--slave
--master-id <arg>
del-node host:port node_id ——(在线删除群集节点,格式为: 主机地址:端口号 nodeid号)
set-timeout host:port milliseconds ——(redis群集节点心跳超时设置,默认为15秒,格式为: 主机地址:端口号 指定的超时时间单位是毫秒)
call host:port command arg arg .. arg ——(使命令在所有节点一起执行,谨慎使用)
import host:port ——(将外部redis节点数据导入群集中)
--from <arg>
--copy
--replace
help (show this help) ——(显示脚本使用帮助)
For check, fix, reshard, del-node, set-timeout you can specify the host and port of any working node in the cluster.
如果本文章有不对的地方,请在评论区留言,谢谢!!~
最后
以上就是畅快柚子为你收集整理的什么是非关系型数据库,Redis概述、安装及部署Redis群集一、什么是非关系型数据库二、Redis简介三、redis实战——搭建redis群集四、扩展——trib.rb脚本的使用的全部内容,希望文章能够帮你解决什么是非关系型数据库,Redis概述、安装及部署Redis群集一、什么是非关系型数据库二、Redis简介三、redis实战——搭建redis群集四、扩展——trib.rb脚本的使用所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复