NoSQL数据库之Redis数据库管理(Redis高级应用之事务处理、持久化操作、pub_sub、虚拟内存)
Redis  /  管理员 发布于 4年前   594
3.事务处理
Redis对事务的支持目前不比较简单。Redis只能保证一个client发起的事务中的命令可以连续的执行,而中间不会插入其他client的命令。当一个client在一个连接中发出multi命令时,这个连接会进入一个事务上下文,该连接后续的命令不会立即执行,而是先放到一个队列中,当执行exec命令时,redis会顺序的执行队列中的所有命令。
redis 127.0.0.1:6379> get age"33"redis 127.0.0.1:6379> multiOKredis 127.0.0.1:6379> set age 10QUEUEDredis 127.0.0.1:6379> set age 20QUEUEDredis 127.0.0.1:6379> exec1) OK2) OKredis 127.0.0.1:6379> get age"20"
如何取消一个事务
redis 127.0.0.1:6379> get age"20"redis 127.0.0.1:6379> multiOKredis 127.0.0.1:6379> set age 30QUEUEDredis 127.0.0.1:6379> set age 40QUEUEDredis 127.0.0.1:6379> discardOKredis 127.0.0.1:6379> get age"20"
可以发现这次2个set age命令都没被执行。discard命令其实就是清空事务的命令队列并退出事务上下文,也就是我们常说的事务回滚。
如下例子可以看到,age由于是个数字,那么它可以有自增运算,但是name是个字符串,无法对其进行自增运算,所以会报错,如果按传统关系型数据库的思路来讲,整个事务都会回滚,但是我们看到redis却是将可以执行的命令提交了,所以这个现象对于习惯于关系型数据库操作的朋友来说是很别扭的,这一点也是redis今天需要改进的地方。
redis 127.0.0.1:6379> incr name(error) ERR value is not an integer or out of rangeredis 127.0.0.1:6379> multiOKredis 127.0.0.1:6379> incr ageQUEUEDredis 127.0.0.1:6379> incr nameQUEUEDredis 127.0.0.1:6379> exec1) (integer) 212) (error) ERR value is not an integer or out of rangeredis 127.0.0.1:6379> get age"21"
乐观锁复杂事务控制:
乐观锁:大多数是基于数据版本( version)的记录机制实现的。即为数据增加一个版本标识,在基于数据库表的版本解决方案中,一般是通过为数据表添加一个"version"实段来实现读取出数据时,将此版本号一同读出,之后更新时,对此版本号加1。此时,将提交数据的版本号与数据库表对应记录的当前版本号进行比对,如果提交的数据版本号大于数据库当前版本号,则予以更新,否则认为是过期数据。
Redis乐观锁实例:假设有一个age的key,我们开2个session来对age进行赋值操作,我们来看一下结果如何。
1)第1步 session1
redis 127.0.0.1:6379> get age"10"redis 127.0.0.1:6379> watch ageOKredis 127.0.0.1:6379> multiOK
2)第2步 session2
redis 127.0.0.1:6379> set age 30OKredis 127.0.0.1:6379> get age"30"
3)第3步 session1
redis 127.0.0.1:6379> set age 30QUEUEDredis 127.0.0.1:6379> exec(nil) //因为有wathch ageredis 127.0.0.1:6379> get age"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被修改就自动做快照。
save 900 1 #900秒内如果超过1个key被修改,则发起快照保存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
appendonly yes //启动aof持久化方式#appendfsync always //收到写命令就立即写入磁盘,最慢,但是保证完全的持久化appendfsync everysec //每秒种写入磁盘一次,在性能和持久化方面做了很好的折中#appendfsync no //完全依赖os,性能最好,持久化没保证
5.发布订阅消息
发布订阅(pub/sub)是一种消息通信模式,主要的目的是解除消息发布者和消息订阅者之间的耦合,Redis作为一个pub/sub的server,在订阅者和发布者之间起到了消息路由的功能。订阅者可以通过subscribe和psubscribe命令向redis server订阅自己感兴趣的消息类型,redis将信息类型称为通道(channel)。当发布者通过publish命令向redis server发送特定类型的信息时,订阅该信息类型的全部client都会收到此消息。
1)第1步 session1
redis 127.0.0.1:6379> subscribe tv1 tv2Reading message... (press Ctrl+C to quit)1) "subscribe"2) "tv1"3) (integer) 11) "subscribe"2) "tv2"3) (integer) 2
2)第2步 session2
redis 127.0.0.1:6379> subscribe tv1Reading message... (press Ctrl+C to quit)1) "subscribe"2) "tv1"3) (integer) 1
3)第3步 session3
redis 127.0.0.1:6379> publish tv1 test(integer) 2 //说明有两个监听redis 127.0.0.1:6379> publish tv2 haha(integer) 1 //说明只有一个监听redis 127.0.0.1:6379>
4)第4步 session1
1) "message"2) "tv1"3) "test"1) "message"2) "tv2"3) "haha"
第4步 session2
1) "message"2) "tv1"3) "test"
6.虚拟内存的使用
Redis的虚拟内存与操作系统的虚拟内存不是一回事,但是思路和目的都是相同的。就是暂时把不经常访问的数据从内存交换到磁盘中,从而腾出宝贵的内存空间用于其他需要访问的数据。尤其是对于redis这样的内存数据库,内存总是不够用的。除了可以将数据分割到多个redis server外,另外能够提高数据库容量的办法就是使用虚拟内存把那些不经常访问的数据交换到磁盘上。
下面是vm相关配置:
vi /usr/local/redis/etc/redis.conf
vm-enabled yes #开启vm功能vm-swap-file /tmp/redis.swap #交换出来的value保存的文件路径vm-max-memory 1000000 #redis使用的最大内存上限vm-page-size 32 #每个页面的大小32字节vm-pages 134217728 #最多使用多少页面vm-max-threads 4 #用于执行value对象换入的工作线程数量
并设置如下配置,确定要使用虚拟内存
really-use-vm yes
说明:本文是我网上学习LAMP兄弟连李捷老师《NoSQL数据库之Redis数据库管理》的学习笔记。
123 在
Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..原梓番博客 在
在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..博主 在
佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..1111 在
佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..路人 在
php中使用hyperf框架调用讯飞星火大模型实现国内版chatgpt功能示例中评论 教程很详细,如果加个前端chatgpt对话页面就完美了..Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号