07_NoSQL数据库之Redis数据库:Redis的高级应用之事务处理、持久化操作、pub_sub、虚拟内存
事務處理
Redis對事務的支持目前還比較簡單。Redis只能保證一個client發起的事務中的命令可以連續的執行,而中間不會插入其他client的命令。當一個client在一個連接中發出multi命令時,這個連接會進入一個事務上下文,該連接后續的命令不會立即執行,而是先放到一個隊列中,當執行exec命令時,redis會順序的執行隊列中的所有命令。
| 127.0.0.1:6379> get age (nil) 127.0.0.1:6379> multi OK????????????????????? //表示事務開始 127.0.0.1:6379> set age 10 QUEUED????????????????? //表示放入隊列 127.0.0.1:6379> set age 20 QUEUED????????????????? //表示這兩個都放入隊列中了 127.0.0.1:6379> exec?????? ?//分別分別返回兩條命令的結果 1) OK????????????????????? 2) OK 127.0.0.1:6379> get age "20" 127.0.0.1:6379> |
?
A:取消一個事務,使用discard
| 127.0.0.1:6379> get age "20" 127.0.0.1:6379> multi OK 127.0.0.1:6379> set age 30 QUEUED 127.0.0.1:6379> set age 40 QUEUED 127.0.0.1:6379> discard OK 127.0.0.1:6379> get age "20" 127.0.0.1:6379> |
可以發現這次2個set age命令都沒被執行。Discard命令其實就是清空事務的命令隊列并退出事務上下文,也就是我們常說的事務回滾。
?
B.樂觀鎖:大多數是基于數據版本(version)的記錄機制實現的。即為數據增加一個版本標識,在基于數據庫表的版本解決方案中,一般是通過數據庫表添加一個“version”字段來實現讀取出數據時,將此版本號一同讀出,之后更新時,對此版本號加1。此時,將提交數據的版本號與數據庫表對應記錄的當前版本號進行比對,如果提交的數據版本號大于數據庫當前版本號,則予以更新,否則認為是過期數據。
?
Redis樂觀鎖實例:假設一個age的key,我們開2個session來對age進行賦值操作,我們來看一下結果如何。
?
watch命令會監視給定的key,當exec時候如果監視的key從調用watch后發生過變化,則整個事務會失敗。也可以調用watch多次監視多個key。這樣就可以對指定的key加樂觀鎖了,注意watch的key是對整個連接有效的,事務也一樣。如果連接斷開,監視和事務都會被自動清除。當然了exec,discard,unwatch命令都會清除連接中的所有監視。
| 127.0.0.1:6379> get age "20" 127.0.0.1:6379> get name (nil) 127.0.0.1:6379> set name toto OK 127.0.0.1:6379> multi OK 127.0.0.1:6379> incr age QUEUED 127.0.0.1:6379> incr name QUEUED 127.0.0.1:6379> exec 1) (integer) 21????????????? //可以看到事務并沒有回滾,執行了一條,后面一條失敗 2) (error) ERR value is not an integer or out of range 127.0.0.1:6379> get age "21" 127.0.0.1:6379> get name "toto" 127.0.0.1:6379> |
從這個例子中可以看到,age由于是個數字,那么它可以有自增運算,但是name是個字符串,無法對其進行自增運算,所以會報錯,如果按傳統關系型數據庫的思路來講,整個事務都會回滾,但是我們看到redis卻是將可以執行的命令提交了,所以這個現象對于習慣關系型數據庫操作的朋友來說是很別扭的,這一點也是redis今天需要改進的地方。
?
持久化機制
Redis是一個支持持久化的內存數據庫,也就是說redis需要經常講內存中的數據同步到硬盤來保證持久化。Redis支持兩種持久化方式:
snapshotting(快照)也是默認方式。(也就是說把數據做一個備份)
append-only file(縮寫aof)的方式。(將寫和更改刪除等操作放到文件中)。
?
快照是默認的持久化方式。這種方式是將內存中數據以快照的方式寫入到二進制文件中。默認的文件名為dump.rdb。可以通過配置自動做快照持久化的方式。我們可以配置redis在n秒內如果超過m個key被修改就自動做快照。
| save 900 1 #900秒內如果超過1個key被修改,則發起快照保存 save 300 10 #300秒內容如超過10個key被修改,則發起快照保存 save 60 10000 |
rdb所在位置:
默認開啟的配置是:
?
aof方式:
由于快照方式是在一定間隔時間做一次的,所以如果redis意外down掉的話,就會丟失最后一次快照后的所有修改。
aof比快照方式更好的持久性,是由于在使用aof時,redis會將每一個收到的寫命令都通過write函數追加到文件中,當redis重啟時會通過重新執行文件中保存的寫命令來在內存中重建整個數據庫的內容。
當然由于os會在內核中緩存write做的修改,所以可能不是立即寫到磁盤上。這樣aof方式的持久化也還是有可能丟失部分修改。
可以通過配置文件告訴redis我們想要通過fsync函數強制os寫入到磁盤的時機。
| appendonly yes?? //啟動aof持久化方式 # appendfsync always?? //收到寫命令就立即寫入磁盤,最慢,但是保證完全的持久化。(表示每次寫都會往文件中寫一次) appendfsync everysec?? //每秒鐘寫入磁盤一次,在性能和持久化方面做了很好的折中。(表示每秒都會執行一次) #appendfsync no?????? //完全依賴os,性能最好,持久化沒保證 |
要修改的配置文件是:vim /usr/local/redis/etc/redis.conf
appendonly的默認參數是no,我們可以給它改成yes
修改同步方式:
重新啟動服務器:/usr/local/redis/bin/redis-server /usr/local/redis/etc/redis.conf
測試運行
| [toto@localhost ~]$ /usr/local/redis/bin/redis-cli 127.0.0.1:6379> set name toto1 (error) NOAUTH Authentication required. 127.0.0.1:6379> auth toto OK 127.0.0.1:6379> set name toto1 OK 127.0.0.1:6379> exit [toto@localhost ~]$ ll 總用量 60 drwxrwxr-x. 2 toto toto 4096 10月 16 19:09 1016 -rw-r--r--. 1 toto toto?? 57 2月? 15 15:59 appendonly.aof -rw-rw-r--. 1 toto toto?? 38 2月? 15 15:56 dump.rdb drwxr-xr-x. 3 root root 4096 10月 13 16:34 mysql drwxrwxr-x. 3 toto toto 4096 2月?? 6 17:24 redis drwxrwxr-x. 2 toto toto 4096 1月? 31 19:58 server drwxrwxr-x. 3 toto toto 4096 10月 16 19:02 shell drwxr-xr-x. 2 toto toto 4096 10月 16 08:58 公共的 drwxr-xr-x. 2 toto toto 4096 10月 16 08:58 模板 drwxr-xr-x. 2 toto toto 4096 10月 16 08:58 視頻 drwxr-xr-x. 2 toto toto 4096 10月 16 08:58 圖片 drwxr-xr-x. 2 toto toto 4096 10月 16 08:58 文檔 drwxr-xr-x. 2 toto toto 4096 10月 16 08:58 下載 drwxr-xr-x. 2 toto toto 4096 10月 16 08:58 音樂 drwxr-xr-x. 2 toto toto 4096 10月 16 10:07 桌面 |
| [toto@localhost ~]$ ls 1016? appendonly.aof? dump.rdb? mysql? redis? server? shell? 公共的? 模板? 視頻? 圖片? 文檔? 下載? 音樂? 桌面 [toto@localhost ~]$ cat appendonly.aof *2 $6 SELECT $1 0 *3 $3 set $4 name $5 toto1 *3 $3 set $4 name $5 toto2 [toto@localhost ~]$ |
由上可以知道aof文件中存的是寫命令。
?
?
發布及訂閱消息
??? 發布訂閱(pub/sub)是一種消息通信模式,主要的目的是解除消息發布者和消息訂閱者之間的耦合,Redis作為一個pub/sub的server,在訂閱者和發布者之間起到了消息路由的功能。訂閱者可以通過subscribe和psubscribe命令向redis server訂閱自己感興趣的消息類型,redis將信息類型稱為通道(channel).當發布者通過publish命令向redis server發送特定類型的信息時,訂閱信息類型的全部client都會收到此消息。
實驗步驟:
打開三個客戶端:
分別使用:/usr/local/redis/bin/redis-cli -a toto登錄客戶端
?
在第一個客戶端輸入:subscribe tv1?? 通過這種方式監聽tv1頻道
在第二個客戶端輸入:subscribe tv1 tv2 通過這種方式監聽tv1,tv2頻道
在第三個客戶端通過public命令發布消息,輸入:以下命令:
?
這樣,在第一個客戶端和第二個客戶端中會監聽到第三個客戶端發布的消息,最后的輸出如下:
客戶端一的消息如下:
客戶端二的消息如下:
?
應用:做消息系統和聊天系統
?
虛擬內存的使用:
???Redis的虛擬內存與操作系統的虛擬內存內存不是一回事兒,但是思路和目的都是相同的。就是暫時把不經常訪問的數據從內存交換到磁盤中,從而騰出寶貴的內存空間用于其他需要訪問的數據。尤其是對于redis這樣的內存數據庫,內存總是不夠用的。除了可以將數據分割到多個redis server外。另外能夠提高數據庫容量的辦法就是使用虛擬內存把那些不經常訪問的數據交換到磁盤上。
?
下面是虛擬內存的配置情況:
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對象換入的工作線程數量
?
注意:自己在2.配置的時候上面的參數不可以配置。
總結
以上是生活随笔為你收集整理的07_NoSQL数据库之Redis数据库:Redis的高级应用之事务处理、持久化操作、pub_sub、虚拟内存的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 大众朗逸蓝牙怎么打开
- 下一篇: 国内知名的油罐车生产厂家有哪些?楚胜汽车