文档章节

Redis学习笔记五:redis的高级实用特性讲解

孟飞阳
 孟飞阳
发布于 2016/07/04 11:29
字数 2988
阅读 1455
收藏 98

一、Redis高级实用特性

1.安全性

        设置客户端连接后进行任何其他指定前需要使用的密码。

        警告:因为redis速度相当快,所以在一台比较好的服务器下,一个外部的用户可以在一秒钟进行150K次的密码尝试,这意味着你需要指定非常强大的密码来防止暴力破解。

[root@localhost ~]# vi /usr/local/redis/etc/redis.conf 

 

        修改配置文件中的如下配置项

1.  #requirepass foobared  
2.  requirepass beijing

        我们设置了连接的口令是beijing。

        重启redis服务

1.  [root@localhost ~]# pkill redis-server  
2.  [root@localhost ~]# /usr/local/redis/bin/redis-server /usr/local/redis/etc/redis.conf  
3.  [root@localhost ~]# /usr/local/redis/bin/redis-cli  
4.  redis 127.0.0.1:6379> keys *  
5.  (error) ERR operation not permitted  
6.  redis 127.0.0.1:6379> auth beijing  
7.  OK  
8.  redis 127.0.0.1:6379> keys *  
9.  1) "name"  
10. redis 127.0.0.1:6379> exit  
11.   
12. [root@localhost ~]# /usr/local/redis/bin/redis-cli -a beijing  
13. redis 127.0.0.1:6379> keys *  
14. 1) "name" 

 

2.主从复制

        Redis主从复制配置和使用都非常简单。通过主从复制可以允许多个slave server拥有和master server相同的数据库副本。

1).Redis主从复制特点:

        a.Master可以拥有多个slave

        b.多个slave可以连接同一个master外,还可以连接到其它slave

        c.主从复制不会阻塞master,在同步数据时,master可以继续处理client请求

        d.提高系统的伸缩性

2).Redis主从复制过程:

        a.Slave与Master建立连接,发送sync同步命令

        b.Master会启动一个后台进程,将数据库快照保存到文件中,同时Master主进程会开始收集新的写命令并缓存

        c.后台完成保存后,就将此文件发送给slave

        d.Slave将此文件保存到硬盘上

3).配置主从服务器

        配置slave服务器很简单,只需要在slave的配置文件中加入以下配置:

1.  slaveof 192.168.1.1 6379 #指定master的ip和端口   

2.  masterauth beijing #这是主机的密码  

1.  [root@localhost ~]# vi /usr/local/redis/etc/redis.conf  
2.  //修改其中的slaveof <maserip> <masterport>、masterauth <master-password>  
3.  [root@localhost ~]# /usr/local/redis/bin/redis-server /usr/local/redis/etc/redis.conf  
4.  [root@localhost ~]# /usr/local/redis/bin/redis-cli -a beijing  
5.  redis 127.0.0.1:6379> keys *  
6.  (empty list or set)  

        配置好后,在Master设置任何key,在Slaver数据库中也会有,表示主从复制成功。

        如我们在主数据库上设置一对键值对

1.  redis 127.0.0.1:6379> set name master  
2.  OK  
3.  redis 127.0.0.1:6379>  

        在从数据库上取这个键

1.  redis 127.0.0.1:6379> get name  
2.  "master"  
3.  redis 127.0.0.1:6379>  

        我们怎么判断哪个是主哪个是从呢?我们只需调用info就可以得到主从信息,我们在从库中执行info如下:

1.  redis 127.0.0.1:6379> info  
2.  role:slave  
3.  master_host:localhost  
4.  master_port:6379  
5.  master_link_status:up  
6.  master_last_io_seconds_ago:10  
7.  master_sync_in_progress:0  
8.  db0:key=1,expires=0  
9.  redis 127.0.0.1:6379> 

        里面的role会显示是Master还是Slave服务器,master_link_status的值是up表示正在连接Master服务器

 

3.事务处理

        Redis对事务的支持目前不比较简单。Redis只能保证一个client发起的事务中的命令可以连续的执行,而中间不会插入其他client的命令。当一个client在一个连接中发出multi命令时,这个连接会进入一个事务上下文,该连接后续的命令不会立即执行,而是先放到一个队列中,当执行exec命令时,redis会顺序的执行队列中的所有命令。

1.  redis 127.0.0.1:6379> get age  
2.  "33"  
3.  redis 127.0.0.1:6379> multi  
4.  OK  
5.  redis 127.0.0.1:6379> set age 10  
6.  QUEUED  
7.  redis 127.0.0.1:6379> set age 20  
8.  QUEUED  
9.  redis 127.0.0.1:6379> exec  
10. 1) OK  
11. 2) OK  
12. redis 127.0.0.1:6379> get age  
13. "20" 

        如何取消一个事务?

1.  redis 127.0.0.1:6379> get age  
2.  "20"  
3.  redis 127.0.0.1:6379> multi  
4.  OK  
5.  redis 127.0.0.1:6379> set age 30  
6.  QUEUED  
7.  redis 127.0.0.1:6379> set age 40  
8.  QUEUED  
9.  redis 127.0.0.1:6379> discard  
10. OK  
11. redis 127.0.0.1:6379> get age  
12. "20"

        可以发现这次2个set age命令都没被执行。discard命令其实就是清空事务的命令队列并退出事务上下文,也就是我们常说的事务回滚。

        如下例子可以看到,age由于是个数字,那么它可以有自增运算,但是name是个字符串,无法对其进行自增运算,所以会报错,如果按传统关系型数据库的思路来讲,整个事务都会回滚,但是我们看到redis却是将可以执行的命令提交了,所以这个现象对于习惯于关系型数据库操作的朋友来说是很别扭的,这一点也是redis今天需要改进的地方。

1.  redis 127.0.0.1:6379> incr name  
2.  (error) ERR value is not an integer or out of range  
3.  redis 127.0.0.1:6379> multi  
4.  OK  
5.  redis 127.0.0.1:6379> incr age  
6.  QUEUED  
7.  redis 127.0.0.1:6379> incr name  
8.  QUEUED  
9.  redis 127.0.0.1:6379> exec  
10. 1) (integer) 21  
11. 2) (error) ERR value is not an integer or out of range  
12. redis 127.0.0.1:6379> get age  
13. "21"  

        乐观锁复杂事务控制:

        乐观锁:大多数是基于数据版本( version)的记录机制实现的。即为数据增加一个版本标识,在基于数据库表的版本解决方案中,一般是通过为数据表添加一个"version"实段来实现读取出数据时,将此版本号一同读出,之后更新时,对此版本号加1。此时,将提交数据的版本号与数据库表对应记录的当前版本号进行比对,如果提交的数据版本号大于数据库当前版本号,则予以更新,否则认为是过期数据。

        Redis乐观锁实例:假设有一个age的key,我们开2个session来对age进行赋值操作,我们来看一下结果如何。

        1)第1步 session1

1.  redis 127.0.0.1:6379> get age  
2.  "10"  
3.  redis 127.0.0.1:6379> watch age  
4.  OK  
5.  redis 127.0.0.1:6379> multi  
6.  OK

        2)第2步 session2

1.  redis 127.0.0.1:6379> set age 30  
2.  OK  
3.  redis 127.0.0.1:6379> get age  
4.  "30" 

        3)第3步 session1

1.  redis 127.0.0.1:6379> set age 30  
2.  QUEUED  
3.  redis 127.0.0.1:6379> exec  
4.  (nil)  //因为有wathch age  
5.  redis 127.0.0.1:6379> get age  
6.  "30" 

 

        watch命令监视给定的key,当exec时候如果监视的key从调用watch后发生过变化,则整个事务会失败。也可以调用watch多次监视多个key。这样就可以对指定的key加乐观锁了。注意watch的key是对整个连接有效的,事务也一样。如果连接断开,监视和事务都会被自动清除。当然,exec、discard、unwatch命令都会清除连接中的所有监视。

        事务回滚:redis的事务实现是如此简单,当然会存在一些问题。第一个问题是redis只能保证事务的每个命令连续执行,但是如果事务中的一个命令失败了,并不回滚其他命令,比如使用的命令类型不匹配。

 

4.持久化机制

        Redis是一个支持持久化的内存数据库,也就是说redis需要经常将内存中的数据同步到硬盘来保证持久化。

        Redis支持两种持久化方式:

        a.snapshotting(快照)也是默认方式

        b.Append-only file(缩写aof)的方式

        1).Snapshotting方式

        快照是默认的持久化方式。这种方式是将内存中数据以快照的方式写入到二进制文件中,默认的文件名为dump.rdb。可以通过配置设置自动做快照持久化的方式。我们可以配置redis在n秒内如果超过m个key被修改就自动做快照。

1.  save 900 1    #900秒内如果超过1个key被修改,则发起快照保存  

2.  save 300 10   #300秒内,如超过10个key被修改,则发起快照保存  

        2).aof方式

        由于快照方式是在一定间隔时间做一次的,所以如果redis意外down掉的话,就会丢失最后一次快照后的所有修改。

        aof比快照方式有更好的持久化性,是由于在使用aof时,redis会将每一个收到的写命令都通过write函数追加到文件中,当redis重启时会通过重新执行文件中保存的写命令来在内存中重建整个数据库的内容。

        当然由于os会在内核中缓存write做的修改,所以可能不是立即写到磁盘上。这样aof方式的持久化也还是有可能会丢失部分修改。

        可以通过配置文件告诉redis我们想要通过fsync函数强制os写入到磁盘的时机,默认的文件名为appendonly.aof[可通过cat方法看,保存的是命令]。

        vi /usr/local/redis/etc/redis.conf

1.  appendonly yes //启动aof持久化方式  

2.  #appendfsync always  //收到写命令就立即写入磁盘,最慢,但是保证完全的持久化  

3.  appendfsync everysec //每秒种写入磁盘一次,在性能和持久化方面做了很好的折中  

4.  #appendfsync no //完全依赖os,性能最好,持久化没保证  

 

5.发布订阅消息

        发布订阅(pub/sub)是一种消息通信模式,主要的目的是解除消息发布者和消息订阅者之间的耦合,Redis作为一个pub/sub的server,在订阅者和发布者之间起到了消息路由的功能。订阅者可以通过subscribe和psubscribe命令向redis server订阅自己感兴趣的消息类型,redis将信息类型称为通道(channel)。当发布者通过publish命令向redis server发送特定类型的信息时,订阅该信息类型的全部client都会收到此消息。

        1)第1步 session1

1.  redis 127.0.0.1:6379> subscribe tv1 tv2  
2.  Reading message... (press Ctrl+C to quit)  
3.  1) "subscribe"  
4.  2) "tv1"  
5.  3) (integer) 1  
6.  1) "subscribe"  
7.  2) "tv2"  
8.  3) (integer) 2 

        2)第2步 session2

1.  redis 127.0.0.1:6379> subscribe tv1  
2.  Reading message... (press Ctrl+C to quit)  
3.  1) "subscribe"  
4.  2) "tv1"  
5.  3) (integer) 1 

        3)第3步 session3

1.  redis 127.0.0.1:6379> publish tv1 test  
2.  (integer) 2  //说明有两个监听  
3.  redis 127.0.0.1:6379> publish tv2 haha  
4.  (integer) 1  //说明只有一个监听  
5.  redis 127.0.0.1:6379>  

        4)第4步 session1

1.  1) "message"  
2.  2) "tv1"  
3.  3) "test"  
4.  1) "message"  
5.  2) "tv2"  
6.  3) "haha"

        第4步 session2

1.  1) "message"  
2.  2) "tv1"  
3.  3) "test"  

 

6.虚拟内存的使用

        Redis的虚拟内存与操作系统的虚拟内存不是一回事,但是思路和目的都是相同的。就是暂时把不经常访问的数据从内存交换到磁盘中,从而腾出宝贵的内存空间用于其他需要访问的数据。尤其是对于redis这样的内存数据库,内存总是不够用的。除了可以将数据分割到多个redis server外,另外能够提高数据库容量的办法就是使用虚拟内存把那些不经常访问的数据交换到磁盘上。

        查了一下官方文档,发现虚拟内存其实一直是不建议使用的。在redis2.4版本以后,干脆就直接去掉了虚拟内存的支持,原因是虚拟内存可以使Redis在内存不够的情况下仍然可以将所有数据序列保存在内存里,这个过程很影响性能,会慢近10倍以上。感谢@卖红薯的提示。所以大家若想继续使用虚拟内存,则最低版本只能是redis2.4了。

        下面是vm相关配置:

         vi  /usr/local/redis/etc/redis.conf

1.  vm-enabled yes                  #开启vm功能  

2.  vm-swap-file /tmp/redis.swap    #交换出来的value保存的文件路径  

3.  vm-max-memory 1000000           #redis使用的最大内存上限  

4.  vm-page-size 32                 #每个页面的大小32字节  

5.  vm-pages 134217728              #最多使用多少页面  

6.  vm-max-threads 4                #用于执行value对象换入的工作线程数量  

        并设置如下配置,确定要使用虚拟内存

1.  really-use-vm yes  

© 著作权归作者所有

共有 人打赏支持
孟飞阳
粉丝 206
博文 964
码字总数 543203
作品 5
朝阳
个人站长
加载中

评论(4)

孟飞阳
孟飞阳

引用来自“卖红薯”的评论

虚拟内存可以使Redis在内存不够的情况下仍然可以将所有数据序列保存在内存里。
vm-enabled no

这个场景非常影响性能,官方新版本已经不支持。
多谢提示8181
卖红薯
卖红薯
虚拟内存可以使Redis在内存不够的情况下仍然可以将所有数据序列保存在内存里。
vm-enabled no

这个场景非常影响性能,官方新版本已经不支持。
孟飞阳
孟飞阳

引用来自“笔阁”的评论

之前写过一个东东,有空的可以配合着试试楼主的讲内容,在线可用。

http://www.hubwiz.com/course/55473be8ebfde9b5591bb813/
7979
笔阁
笔阁
之前写过一个东东,有空的可以配合着试试楼主的讲内容,在线可用。

http://www.hubwiz.com/course/55473be8ebfde9b5591bb813/
2018年程序员涨薪必备——24本经典纸质书

程序员必读24款经典 001 豆瓣评分:8.7 推荐: 本书论述了数学在现代计算机行业的多种应用,涉及语言分析、翻译、输入法,还有网页的搜索、排名、分类,以及导航、密码学和大数据等多个方面。...

野梦M
01/05
0
0
redis学习笔记(三)之其他命令和特性

redis学习笔记(一)之安装测试 redis学习笔记(二)之数据类型 一、基本特性 1、reids 默认端口:6379; 2、默认支持16个数据库,建立连接后自动选择0号数据库,建议不同的应用使用不同的r...

憨豆公子
2016/08/19
21
0
Redis学习笔记之Redis字符串String(五)

Redis学习笔记之Redis字符串String(五) 特点【转】 字符串类型最大的特点就是单key单value。 string是redis最基本的类型,而且string类型是二进制安全的。 redis的string可以包含任何数据。比...

残风vs逝梦
2016/10/05
36
0
周末好福利:你离数据库大神也许只差一本专攻好书

在时间与实战的校验下,各类数据库顺应市场需求不断迭代,由此发展出了层出不穷的新能力……于是,想要把握技术趋势,掌握最优技能,读书无疑是IT人精进的优选方式。 为了帮助大家巩固、提高...

dbaplus社群
09/03
0
0
.Net免费公开课视频+资料+源码+经典牛逼 汇总篇【持续更新】

博主推荐一:WP8.1最经典培训教程 博主点评:经典Windows Phone8.1 Runtime API培训最经典教程,此教程由传智播客蒋坤老师录制的一整套WP8.1入门级视频教程,讲授内容非常广、深入而且非常适...

aicoder
2014/11/04
0
0

没有更多内容

加载失败,请刷新页面

加载更多

android -------- MVP+DataBinding 的使用

天来说说MVP+DataBinding 的使用 以一个登录案例来讲解 布局:(ConstraintLayout 作为根布局) <layout> <data> <variable name="onClick" ......

切切歆语
33分钟前
1
0
阿里十年Java架构经验总结,这几点尤为重要!

你有没有静下心来思考过:同样是做了x年Java开发,为什么你的技术比别人差很多?为什么别人每月28K你却只有10K? 其实技术水平的高低和个人智商关系不大(毕竟能做Java编程开发大家都不会差)...

别打我会飞
37分钟前
1
0
Ubuntu 中安装和配置 Caddy 服务

首先访问:https://caddyserver.com/download 选择操作系统、插件和授权类型,点击 Download 下载编译好的文件包,或者执行页面最下面的一键安装脚本,完成 caddy 的安装。 安装完成后,/us...

八风不动
53分钟前
2
0
java代码效率优化

1、 尽量指定类的final修饰符 带有final修饰符的类是不可派生的。 2、 尽量重用对象。 3、 尽量使用局部变量,调用方法时传递的参数以及在调用中创建的临时变量都保存在栈(Stack)中,速度较...

踏破铁鞋无觅处
今天
3
0
程序员的几款利器

1. 作为程序员,最希望的就是自己的代码能够在一个云平台上保留下来,gitlab等等这些很多。但是我这里推荐“码云平台”码云平台和开源中国可以直接关联起来。开源中国可以记录博客,当然也是...

ChinaHYF
今天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部