1. 程式人生 > >rediis介紹與安裝,持久化存儲,發布訂閱,事務

rediis介紹與安裝,持久化存儲,發布訂閱,事務

server -o 數據庫中的事務 內存分配 exp 復雜 mar 註意 class

一:redis簡介

一:介紹

1:簡介:

redis是一個key-value存儲系統。和Memcached類似,它支持存儲的value類型相對更多,包括string(字符串)、list(鏈表)、set(集合)、zset(sorted set --有序集合)和hash(哈希類型)。這些數據類型都支持push/pop、add/remove及取交集並集和差集及更豐富的操作,而且這些操作都是原子性的。在此基礎上,redis支持各種不同方式的排序。與memcached一樣,為了保證效率,數據都是緩存在內存中。區別的是redis會周期性的把更新的數據寫入磁盤或者把修改操作寫入追加的記錄文件,並且在此基礎上實現了master-slave(主從)同步

2:主要功能:
高速讀寫
數據類型豐富
支持持久化
多種內存分配及回收策略
支持事務
消息隊列、消息訂閱
支持高可用
支持分布式分片集群

3:redis與memcached對比:

Memcached:
優點:高性能讀寫、單一數據類型、支持客戶端式分布式集群、一致性hash
   多核結構、多線程讀寫性能高。
缺點:無持久化、節點故障可能出現緩存穿透、分布式需要客戶端實現、跨機房數據同步困難、架構擴容復雜度高
   

Redis:

優點:高性能讀寫、多數據類型支持、數據持久化、高可用架構、支持自定義虛擬內存、支持分布式分片集群、單線程讀寫性能極高
缺點:多線程讀寫較Memcached慢



memcache與redis在讀寫性能的對比:

  memcached 由於是多核結構能高效利用cpu,所以適合多用戶訪問,每個用戶少量的rw
  redis 是單核結構,適合少用戶訪問,每個用戶大量rw

4:Redis使用場景介紹

Memcached:多核的緩存服務,更加適合於多用戶並發訪問次數較少的應用場景

Redis:單核的緩存服務,單節點情況下,更加適合於少量用戶,多次訪問的應用場景。

   所以解決redis無法高效利用cpu的問題,可以在單機上采用多實例架構,配合redis集群出現,這樣對cpu的利用率就高了。

二:redis的安裝與部署

一:linux下安裝:

下載:
wget http://download.redis.io/releases/redis-3.2.12.tar.gz
解壓:
上傳至 /data
tar xzf redis-3.2.12.tar.gz
mv redis-3.2.12 redis
安裝:
cd redis
make
啟動:
src/redis-server & # 加個‘&’ 符號代表後臺啟動的意思


環境變量:
vim /etc/profile
export PATH=/data/redis/src:$PATH
source /etc/profile


redis-server &

redis-cli
127.0.0.1:6379> set num 10
OK
127.0.0.1:6379> get num
10

二:redis基本管理操作

1:基礎配置文件介紹:
[root@standby ~]# redis-cli shutdown

mkdir /data/6379

cat >>/data/6379/redis.conf <<EOF
daemonize yes
port 6379
logfile /data/6379/redis.log
dir /data/6379
dbfilename dump.rdb
EOF


重啟redis
redis-cli shutdown
redis-server /data/6379/redis.conf
netstat -lnp|grep 63


+++++++++++配置文件說明++++++++++++++
redis.conf
是否後臺運行:
daemonize yes
默認端口:
port 6379
日誌文件位置
logfile /var/log/redis.log
持久化文件存儲位置
dir /data/6379
RDB持久化數據文件:
dbfilename dump.rdb
+++++++++++++++++++++++++

redis-cli
127.0.0.1:6379> set name zhangsan
OK
127.0.0.1:6379> get name
"zhangsan"

2:redis安全配置

redis-cli 客戶端登錄命令常用參數說明

redis-cli 剛裝完,可以在redis服務器上直接登錄redis
-p 6379 指定端口號
-h 指定鏈接地址
-a 指定鏈接密碼

但是redis默認開啟了保護模式,只允許本地回環地址登錄並訪問數據庫,外部登錄需要設置一下。

1):

  禁止protected-mode

  protected-mode yes/no (保護模式,是否只允許本地訪問)

2):

  ①Bind :指定IP進行監聽:
  echo "bind 10.0.0.200 127.0.0.1" >>/data/6379/redis.conf
  ②增加requirepass {password}:
  echo "requirepass 123" >>/data/6379/redis.conf

----------驗證-----

重啟redis
redis-cli shutdown
redis-server /data/6379/redis.conf
[root@python-linux ~]# redis-cli -a 123
127.0.0.1:6379> set name zhangsan
OK

三:redis持久化存儲

一:redis持久化(內存數據保存到磁盤)
作用:可以有效防止,在redis宕機後,緩存失效的問題.

兩種方式:RDB AOF

RDB 持久化
可以在指定的時間間隔內生成數據集的時間點快照(point-in-time snapshot)。
優點:速度快,適合於用做備份,主從復制也是基於RDB持久化功能實現的。
缺點:會有數據丟失

rdb持久化核心配置參數:

vim /data/6379/redis.conf
dir /data/6379
dbfilename dump.rdb

save 900 1
save 300 10
save 60 10000

配置分別表示:
900秒(15分鐘)內有1個更改
300秒(5分鐘)內有10個更改
60秒內有10000個更改
----------
AOF 持久化(append-only log file)
記錄服務器執行的所有寫操作命令,並在服務器啟動時,通過重新執行這些命令來還原數據集,類似於mysql的binlog。
AOF 文件中的命令全部以 Redis 協議的格式來保存,新命令會被追加到文件的末尾。
優點:可以最大程度保證數據不丟
缺點:日誌記錄量級比較大

舉個例子:
set a 1
set a 2
set a 3

那麽RDB只記錄a的最終值,即3
而AOF會將3條命令都記錄,顯得比較臃腫
-------------

AOF持久化配置兩行參數就可以
# 開啟
appendonly yes
# 每秒觸發一次 一般級別配置成everysec就可以了
appendfsync everysec

appendonly yes/no #是否打開aof日誌功能

appendfsync always #每1個命令,都立即同步到aof

appendfsync everysec #每秒寫1次

appendfsync no #寫入工作交給操作系統,由操作系統判斷緩沖區大小,統一寫入到aof.

四:redis發布訂閱

一:什麽是發布訂閱

發布訂閱模式又叫觀察者模式,它定義對象間的一種一對多的依賴關系,當一個對象的狀態發生改變時,所有依賴它的對象都將得到通知

Redis 發布訂閱(pub/sub)是一種消息通信模式:發送者(pub)發送消息,訂閱者(sub)接收消息。

二:簡單說明與使用

Linux下:

發布訂閱
PUBLISH channel msg
  將信息 message 發送到指定的頻道 channel
SUBSCRIBE channel [channel ...]
  訂閱頻道,可以同時訂閱多個頻道
UNSUBSCRIBE [channel ...]
  取消訂閱指定的頻道, 如果不指定頻道,則會取消訂閱所有頻道
PSUBSCRIBE pattern [pattern ...]
  訂閱一個或多個符合給定模式的頻道,每個模式以 * 作為匹配符,比如 it* 匹配所 有以 it 開頭的頻道( it.news 、 it.blog 、 it.tweets 等等), news.* 匹配所有 以 news. 開頭的頻道( news.it 、       news.global.today 等等),諸如此類
PUNSUBSCRIBE [pattern [pattern ...]]
  退訂指定的規則, 如果沒有參數則會退訂所有規則
PUBSUB subcommand [argument [argument ...]]
  查看訂閱與發布系統狀態
註意:使用發布訂閱模式實現的消息隊列,當有客戶端訂閱channel後只能收到後續發布到該頻道的消息,之前發送的不會緩存,必須Provider和Consumer同時在線。

發布訂閱例子:

窗口1:
#收聽者訂閱頻道
127.0.0.1:6379> SUBSCRIBE baodi

窗口2:

# 發布者往頻道發布消息,訂閱者自動收到消息
127.0.0.1:6379> PUBLISH baodi "jin tian zhen kaixin!"

訂閱多頻道:
窗口1:
127.0.0.1:6379> PSUBSCRIBE wang*
窗口2:
127.0.0.1:6379> PUBLISH wangbaoqiang "jintian zhennanshou "

三:python+redis實現發布訂閱

發布者

# -*- coding:utf-8 -*-
# Author : liuqingzheng
# Data : 2018/11/23 19:17

import redis
conn=redis.Redis(host=127.0.0.1,port=6379)
# 頻道,發布內容
conn.publish(98k,hello world)

訂閱者

# -*- coding:utf-8 -*-
# Author : liuqingzheng
# Data : 2018/11/23 19:20
import redis
conn=redis.Redis(host=127.0.0.1,port=6379)
# 拿到發布者對象
pub=conn.pubsub()
# 訂閱頻道
pub.subscribe(98k)
# 可以訂閱多個頻道
# pub.subscribe(‘998‘)
# 循環等待
while True:
    # 接收到消息,解析響應
    msg=pub.parse_response()
    print(msg)

一些應用場景:

1 構建實時消息系統,比如普通的即時聊天,群聊等功能

2 在我們的分布式架構中,常常會遇到讀寫分離的場景,在寫入的過程中,就可以使用redis發布訂閱,使得寫入值及時發布到各個讀的程序中,就保證數據的完整一致性

3 在一個博客網站中,有100個粉絲訂閱了你,當你發布新文章,就可以推送消息給粉絲們

五:redis事務及鎖

一:簡介

redis中的事務跟關系型數據庫中的事務是一個相似的概念,但是有不同之處。關系型數據庫事務執行失敗後面的sql語句不在執行,而redis中的一條命令執行失敗,其余的命令照常執行。 redis中開啟一個事務是使用multi,相當於begin\start transaction,exec提交事務,discard取消隊列命令(非回滾操作)。

技術分享圖片

redis的事務是基於隊列實現的。redis開始事務後每執行一條命令,都加入到隊列中,並未真的執行。mysql的事務是基於事務日誌實現的。

開啟事務功能時(multi)
multi
command1
command2
command3
command4

4條語句作為一個組,並沒有真正執行,而是被放入同一隊列中。
如果,這時執行discard,會直接丟棄隊列中所有的命令,而不是做回滾。

exec
當執行exec時,隊列中所有操作,要麽全成功要麽全失敗


二:redis事務中的鎖

redis執行事務時為樂觀鎖工作原理,相當於不加鎖,mysql執行事務時為悲觀鎖。

例子1:

技術分享圖片
窗口1:
127.0.0.1:6379> multi 
OK
127.0.0.1:6379> set a 1
QUEUED
127.0.0.1:6379> set b 2
QUEUED
127.0.0.1:6379> 

窗口2:
127.0.0.1:6379> multi 
OK
127.0.0.1:6379> set a 3
QUEUED
127.0.0.1:6379> set b 4
QUEUED
127.0.0.1:6379> 

窗口1:
127.0.0.1:6379> exec

窗口2:
127.0.0.1:6379> exec
127.0.0.1:6379> get a
"3"
127.0.0.1:6379> get b
"4"

可以看到,兩個事務都執行成功,並且後exec的覆蓋前面的。假設現在是買票的場景,只剩1張票,A和B都生成訂單了,A先付款會提示付款成功,B後付款也會提示付款成功,這亂套了。
View Code

可以運用watch 使得執行事務類似悲觀鎖

例子2:

技術分享圖片
模擬搶票
窗口1:
127.0.0.1:6379> set ticket 1
OK
127.0.0.1:6379> watch ticket
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set ticket 0
QUEUED

窗口2:
127.0.0.1:6379> watch ticket
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set ticket 0
QUEUED

窗口1:
127.0.0.1:6379> exec
1) OK

窗口2:
127.0.0.1:6379> exec
(nil)

窗口1提交成功後,窗口2提交失敗,完成需求
View Code

rediis介紹與安裝,持久化存儲,發布訂閱,事務