1. 程式人生 > >NoSQL之Redis入門筆記

NoSQL之Redis入門筆記

 Redis 

1.Redis介紹

1.1 NoSQL:一類新出現的資料庫(not only sql),它的特點

  • 不支援sql語法
  • 儲存結構跟傳統關係型資料庫中的那種關係表完全不同,nosql中儲存的資料都是key value形式
  • NoSQL的世界中沒有一種通用的語言,每種nosql資料庫都有自己的api和語法,以及擅長的業務場景
  • NoSQL中的產品種類相當多:
    • MongoDB
    • Redis
    • Hbase hadoop
    • Cassandra hadoop

1.2 Redis簡介

  • Redis是一個開源的使用ANSI C語言編寫,支援網路,可基於記憶體亦可持久化的日誌型,key-value資料庫,並提供多種語言的API。從2010年3月15日起,Redis的開發工作有Vmware主持。從2013年5月開始,Redis的開發由Pivotal贊助。
  • Redis是NoSQL技術陣營中的一員,它通過多種鍵值型別來適應不同場景下的儲存需求,藉助一些高層級的介面使用其可以勝任,如快取、佇列系統的不同角色

1.3 Redis特性

  Redis與其他key – value 快取產品由以下三個特點:

  • Redis支援資料的持久化,可以將記憶體中的資料儲存在磁碟中,重啟的時候可以再次載入進行使用。
  • Redis不僅僅支援簡單的key-value型別的資料,同時還提供list,set,zset,hash等資料結構的儲存。
  • Redis支援資料的備份,即master-slave模式的資料備份。

1.4 NoSQL和SQL資料庫的比較

  • 適用場景不同:sql資料庫適合用於關係特別複雜的資料查詢場景,nosql反之
  • “事務”特性的支援:sql對事務的支援非常完善,而nosql基本不支援事務
  • 兩者在不斷地取長補短,呈現融合趨勢

1.5 Redis優勢

  • 效能極高-Redis能讀的速度是110000次/s,寫的速度是81999次/s。
  • 豐富的資料型別-Redis支援二進位制案例的strings,lists,hashes,sets及ordered sets資料型別操作。
  • 原子-Redis的所有操作都是原子性的,同時還支援對幾個操作全並後的原子性執行。原子性就是操作沒有多程序多執行緒。
  • 豐富的特性-Redis還支援publish/subscribe 通知,key過期等等特性。

1.6 Redis應用場景

  • 用來做快取(ehcache/memcached)--redis的所有資料是放在記憶體中的(記憶體資料庫)
  • 可以在某些特定應用場景下替代傳統資料庫—比如社交類應用
  • 在一些大型系統中,巧妙地實現一些特定的功能:session共享,購物車
  • 只要你有豐富的想象力,redis可以給你無限的驚喜

2.Redis安裝

我們安裝兩臺為之後的主從和叢集做準備

系統:CentOS 7

伺服器:2臺

redis-01 :IP地址:172.16.1.74 

redis-02 :IP地址:172.16.1.111

關閉selinux,關閉防火牆...基礎優化~

安裝目錄:/usr/local/

安裝包版本:redis-3.2.12.tar.gz(比較穩定的3.2)

 1 cd /usr/local/
 2 wget http://download.redis.io/releases/redis-3.2.12.tar.gz 
 3 tar xf redis-3.2.12.tar.gz
 4 cd redis-3.2.12
 5 make && make install 
 6 
 7 mkdir /etc/redis
 8 cp redis.conf /etc/redis/redis.conf
 9 /usr/local/bin 下會出現這些程式
10 redis-server           redis伺服器啟動命令
11 redis-cli                 redis命令列客戶端
12 redis-benchmark    redis效能測試工具
13 redis-check-aof      AOF檔案修復工具
14 redis-check-rdb      RDB檔案檢索工具
15 redis-sentinel        redis哨兵程序(用於主從自動切換)
安裝程式碼

 3.Redis核心配置

  我修改成適合學習的環境

  • 繫結ip:預設本地訪問,我們方便連線先繫結本地ip訪問,正式環境可以按需求繫結ip 

  bind 172.16.1.74

  • 埠,預設為6379,正式環境可以改成其他埠,增加安全性

  port 6379

  • 是否以守護程序執行,當然要,好處是退出終端程式不會停止預設是no,這裡我們設定成yes

  daemonize yes

  • 資料檔案

  dbfilename dump.rdb

  • 資料檔案儲存路徑 預設./ 我們修改自己指定的路徑

  dir /backup/redis

  • 日誌檔案

  logfile /var/log/redis/redis-server.log

  • 資料庫,預設有16個

  database 16

  • 主從複製配置,先不開啟

  #slaveof

  我們建立一下需要的目錄

  mkdir /backup/redis/ /var/log/redis -p

 

其他詳細配置介紹參考

https://blog.csdn.net/ljphilp/article/details/52934933

4.伺服器和客戶端命令

  • 伺服器端的命令為redis-server
  • 可以使用help檢視幫助文件

  redis-server –help

  • 啟動

  redis-server /etc/redis/redis.conf

  • 停止

  ps -ef|grep redis 檢視pid

  kill -9 pid

  • 連線

  redis-cli

  • 測試:輸入ping 返回PONG為OK

  PONG     

  預設用第一個資料庫

  • 切換資料庫 資料庫沒有名稱,預設有16個 通過0-15來標識,連線redis預設選擇第一個資料庫

  select n   #n為資料庫編號

 

其他詳細配置介紹參考

https://blog.csdn.net/ljphilp/article/details/52934933

5.資料操作

5.1資料結構

  • redis是key-value的資料結構,每一條資料都是一個鍵值對
  • 鍵的型別是字串
  • 注意:鍵不能重複
  • 值得型別分為五種:
    • 字串string
    • 雜湊hash
    • 列表list
    • 集合set
    • 有序集合zset

資料庫操作行為

  • 儲存
  • 修改
  • 獲取
  • 刪除

中文網參考:http://redis.cn/commands.html

5.3string型別

5.3.1儲存值

如果設定的鍵不存在則為新增,如果設定的鍵已經存在則修改

  • 設定鍵值

  set key value

  例:設定鍵為name 值為wsy的資料

  set name wsy

  • 設定鍵值及過期時間,以秒為單位

  setex key seconds value

  例:設定鍵為age 值為20過期時間為3秒的資料 

  

  • 設定多個鍵值

  mset key1 value1 key2 value2

  例:設定鍵為a1值為haha、鍵為a2值為hehe、鍵為a3值為xx

  

  • 追加值

  append key value

  例:向a1 中追加值 heihei  

  append a1 heihei
   

5.3.2獲取值

  • 獲取:根據鍵獲取值,如果不存在此鍵則返回nil

  get key

  例:獲取鍵name的值

  

  • 根據多個鍵獲取多個值

  mget key1 key2

  例:獲取鍵a1、a2、a3的值

  

5.4鍵命令

  • 查詢鍵,引數支援正則表示式

  keys pattern

  例:檢視所有鍵

  

  

  

  • 判斷鍵是否存在,如果存在返回1,不存在返回0

  exists key1

  例:判斷鍵是否存在

  

  • 刪除鍵及對應的值

  del key1 key2

  例:刪除鍵a3 user name

  

  • 設定過期時間,以秒為單位,如果沒有指定過期時間則一直存在,直到使用DEL移除

  expire key seconds

  例:設定鍵u2 過期時間為5秒

  

五秒後   

  

  • 檢視有效時間,以秒為單位

  ttl key

  例:檢視鍵a2的有效時間

  

5.5hash型別

  • hash用於儲存物件,物件的結構為屬性、值
  • 值得型別為string

5.5.1增加修改

  • 設定單個屬性

  hset key field value

  例:設定鍵user得屬性name為wsy

  

  • FAQ:

原因:

強制關閉redis快照導致不能持久化。解決方案:

  • 執行config set stop-writes-on-bgsave-error no 命令後,關閉配置想stop-writes-on-bgsave-error解決該問題。

 

  • 設定多個屬性

  hmset key field1 value1 field2 value2

  例:設定鍵u2的屬性name為wsy、屬性age為20

   

5.5.2獲取

  • 獲取指定鍵所有的屬性

  hkeys key

  例:獲取鍵u2的所有屬性

  

  • 獲取一個屬性的值

  hget key field

  例:獲取鍵u2屬性name的值

  

  • 獲取多個屬性的值

  hmget key field1 field2

  例:獲取鍵u2屬性name、age的值

  

  • 獲取所有屬性的值

  hvals key

  例:獲取鍵u2所有屬性的值

  

5.5.3刪除

  • 刪除整個hash鍵及值,使用del命令
  • 刪除屬性,屬性對應的值會被一起刪除

  hdel key field1 field2...

  例:刪除鍵u2的屬性age

   

5.6 list型別

  • 列表的元素型別為string
  • 按照插入順序排序

5.6.1 增加

  • 在左側插入資料

  lpush key value1 value2 ...

  例:從鍵為c1的列表左側加入資料a,b,c

  

  

  • 在右側插入資料

  rpush key value1 value2 ...

  例:從鍵為c1的列表右側加入資料x,y,z

  

  • 在指定元素的前或後插入新元素

  linsert key before 或after 現有元素 新元素

  例:在鍵為c1的列表中元素b前加入3

  

5.6.2 獲取

  • 返回列表例的指定範圍內的元素

    start,stop為元素的下表索引

    索引從左側開始,第一個元素為0

    索引可以是負數,表示從尾部開始計數,如-1表示最後一個元素

  lrange key start stop

  例:獲取鍵為c1的列表所有元素

  lrange c1 0 -1

  

5.6.3 設定指定索引位置元素值

  • 索引從左側開始,第一個元素為0
  • 索引可以是負數,表示尾部開始計數,如-1表示最後一個元素

  lset key index value

  例:修改鍵為c1的列表中下標為2的元素值為lset

  

 

5.6.4 刪除

  • 刪除指定元素

    將列表中前count次出現的值為value的元素移除

    count>0:從頭往後移除

    count<0:從後往前移除

    count=0:移除所有

  lrem key count value

  例:向列表list1中加入元素a,b,c,a,b,c,然後從列表右側開始刪除2個b

  

5.7 set型別

  • 無序集合
  • 元素為string型別
  • 元素具有唯一性,不重複
  • 說明:對於集合沒有修改操作

 

5.7.1 增加

  • 新增元素

  sadd key member1 member2 ...

  例:向鍵set1的集合中新增元素mayun,mahuateng,leijun

  

 

5.7.2 獲取

  • 返回所有元素

  smembers key

  例:獲取鍵set1的集合中所有元素

  

 

5.7.3 刪除

  • 刪除指定元素

  srem key

  例:刪除鍵a3的集合中元素mahuateng

  

 

5.8 zset型別

  • sorted set 有序集合
  • 元素為string型別
  • 元素具有唯一性,不重複
  • 每個元素都會關聯一個double型別的score,表示權重,通過權重將元素從小到大排序
  • 說明:沒有修改操作

5.8.1 增加

  • 新增

  zadd key score1 member1 score2 member2

  例:向鍵zset1的集合中新增元素a b c d 權重分別為4 3 5 2

  

 

5.8.2 獲取

  • 返回指定範圍內的元素
  • start、stop為元素的下表索引
  • 索引從左側開始,第一個元素為0
  • 索引可以是負數,表示從尾部開始計數,如-1表示最後一個元素

  zrange key start stop

  例:獲取zset1的集合中所有元素

  

 

  • 返回score值在min和max之間的成員

  zrangebyscore key min max

  例:獲取zset1集合中score 2-3之間得成員

  

 

  • 返回成員member的score值

  zscore key member

  例:獲取zset1集合中a b c d 的score值

  

 

5.8.3 刪除

  • 刪除指定元素

  zrem key member1 member2 ...

  例:刪除集合zset1中元素b

  

 

  • 刪除權重在指定範圍的元素

  zremrangebyscore key min max

  例:刪除集合zset1中許可權為1,2的元素

  

 

命令參考文件:http://doc.redisfans.com/

6.redis主從多例項配置

6.1主從概念

  • 一個master可以有多個slave,一個slave又可以擁有多個slave,如此下去,形成了強大的多級伺服器叢集架構
  • master用來寫資料,slave用來讀資料,每次主寫入資料都會同步到從伺服器,經統計:網站的讀寫比率時10:1
  • 通過主從配置可以實現讀寫分離
  • master和slave都是redis例項(redis服務)

6.2多例項

  • 同一個服務用不同的配置檔案啟動,監聽不同的埠,不同的pid等。

6.3主從配置

1 其他預設即可,很隨意
2 bind 172.16.1.74
3 port 6379
4 pidfile /var/run/redis_6379.pid
5 daemonize yes
主配置檔案
1 cd /etc/redis/
2 cp redis.conf slave.conf
3 vim slave.conf
4 bind 172.16.1.74
5 port 6380                                       #同一臺伺服器監聽其他埠
6 pidfile /var/run/redis_6380.pid
7 daemonize yes
8 slaveof 172.16.1.74 6379                #這步必須要加
從配置檔案

啟動兩個例項

redis-server /etc/redis/redis.conf

redis-server /etc/redis/slave.conf

 1 檢視主
 2 redis-cli info Replication
 3 # Replication
 4 # 角色 主
 5 role:master
 6 # 幾個從
 7 connected_slaves:1
 8 # 從服務的IP 埠
 9 slave0:ip=127.0.0.1,port=6380,state=online,offset=141,lag=1
10 master_repl_offset:141
11 repl_backlog_active:1
12 repl_backlog_size:1048576
13 repl_backlog_first_byte_offset:2
14 repl_backlog_histlen:140
15 檢視從
16 redis-cli -p 6380 info Replication
17 # Replication
18 role:slave
19 master_host:0.0.0.0
20 master_port:6379
21 master_link_status:up
22 master_last_io_seconds_ago:6
23 master_sync_in_progress:0
24 slave_repl_offset:211
25 slave_priority:100
26 slave_read_only:1
27 connected_slaves:0
28 master_repl_offset:0
29 repl_backlog_active:0
30 repl_backlog_size:1048576
31 repl_backlog_first_byte_offset:0
32 repl_backlog_histlen:0

測試

連線主從

因為從庫只讀所以寫入的時候會報錯

可以獲取到我們在主庫set的資料

主從配置完畢

7.redis叢集

  • 之前我們已經掌握主從的概念,一主可以多從,如果同時的訪問量過大(1000w),主伺服器肯定會掛掉,資料服務就怪掉了或者發生自然災難
  • 概念:叢集是一組相互獨立的,通過高速網路互連的計算機,它們構成了一個組,並以單一系統的模式加以管理,一個客戶與叢集相互作用時,叢集像是一個獨立的伺服器,叢集配置時用於提高可用性和可縮放性,一句話概括叢集:一組通過網路連線的計算機,共同對外提交服務,像一個獨立的伺服器。

7.1 搭建叢集

7.1.1 建立節點

我們建立6個節點(例項):監聽埠分別為 7000-7005

主機 redis-01

ip:172.16.1.74

 1 cd /etc/redis/
 2 vim 7000.conf
 3 port 7000
 4 bind 172.16.1.74
 5 daemonize yes
 6 pidfile 7000.pid
 7 cluster-enabled yes
 8 cluster-config-file 7000_node.conf
 9 cluster-node-timeout 15000
10 appendonly yes
建立節點1配置檔案
 1 cp 7000.conf 7001.conf
 2 修改配置如下
 3 port 7001
 4 bind 172.16.1.74
 5 daemonize yes
 6 pidfile 7001.pid
 7 cluster-enabled yes
 8 cluster-config-file 7001_node.conf
 9 cluster-node-timeout 15000
10 appendonly yes
建立節點2配置檔案
 1 cp 7000.conf 7002.conf
 2 修改配置如下
 3 port 7002
 4 bind 172.16.1.74
 5 daemonize yes
 6 pidfile 7002.pid
 7 cluster-enabled yes
 8 cluster-config-file 7002_node.conf
 9 cluster-node-timeout 15000
10 appendonly yes
建立節點3配置檔案
  • 三個檔案的配置區別在port pidfile cluster-config-file三項
  • 使用配置檔案啟動redis服務

啟動並檢查:

redis-server 7000.conf

redis-server 7001.conf

redis-server 7002.conf

主機 redis-02

ip:172.16.1.111

 1 cd /etc/redis/
 2 vim 7003.conf
 3 port 7003
 4 bind 172.16.1.111
 5 daemonize yes
 6 pidfile 7003.pid
 7 cluster-enabled yes
 8 cluster-config-file 7003_node.conf
 9 cluster-node-timeout 15000
10 appendonly yes
建立節點4配置檔案
1 vim 7004.conf
2 port 7004
3 bind 172.16.1.111
4 daemonize yes
5 pidfile 7004.pid
6 cluster-enabled yes
7 cluster-config-file 7004_node.conf
8 cluster-node-timeout 15000
9 appendonly yes
建立節點5配置檔案
1 vim 7005.conf
2 port 7005
3 bind 172.16.1.111
4 daemonize yes
5 pidfile 7005.pid
6 cluster-enabled yes
7 cluster-config-file 7005_node.conf
8 cluster-node-timeout 15000
9 appendonly yes
建立節點6配置檔案

啟動並檢查:

redis-server 7003.conf

redis-server 7004.conf

redis-server 7005.conf

7.1.2 建立叢集

安裝ruby

FAQ:不裝會失敗

1 wget https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.3.tar.gz
2 tar xf ruby-2.5.3.tar.gz
3 cd ruby-2.5.3
4 ./configure  --prefix=/usr/local/ruby 
5 make && make install
6 ln -s /usr/local/ruby/bin/ruby /usr/bin/ruby
7 ln -s /usr/local/ruby/bin/gem /usr/bin/gem
8 gem install redis                                         #安裝ruby的redis介面
ruby編譯安裝

開始建立

1 cp /usr/local/redis/src/redis-trib.rb /usr/local/bin/
2 
3 redis-trib.rb create --replicas 1 172.16.1.74:7000 172.16.1.74:7001 172.16.1.74:7002 172.16.1.111:7003 172.16.1.111:7004 172.16.1.111:7005

命令replicas 1  :建立1個叢集:會分配三個節點,每個節點主從服務 一共6個redis服務

如圖 三個主: 172.16.1.74:7000         三個從: 172.16.1.111:7004

                        172.16.1.74:7001                        172.16.1.111:7005

                        172.16.1.111:7003                       172.16.1.74:7002

 

主節點的槽slots 用於儲存資料 一共有16384個槽

172.16.1.74:7000    槽 0-5460

172.16.1.74:7001    槽 5461-10922

172.16.1.111:7003   槽 10923-16383

 

7.1.3 redis叢集寫資料原理

  • redis cluster在設計的時候,就考慮到了去中心化,去中介軟體,也就是說,叢集中的每個節點都是平等的關係,都是對等的,每個節點都儲存各自的資料和整個叢集的狀態,每個節點都和其他所有節點連線,而且這些連線保持活躍,這樣就保證了我們只需要連線叢集中的任意一個節點,就可以獲取到其他節點的資料

 

  • redis叢集沒有並使用傳統的一致性雜湊來分配資料,而是採用另外一種叫做雜湊槽(hash slot)的方式來分配的。redis cluster預設分配了16384個slot,當我們set一個key時,會用CRC16演算法來取模得到所屬的slot,然後將這個key分到雜湊槽區間的節點上,具體演算法就是CRC16(key)% 16384。所以我們在測試的時候看到set和get的時候直接跳轉到那個埠的節點

 

  • redis叢集會把資料存在一個master節點,然後在這個master和其對應的salve之間進行資料同步。當讀取資料時,也根據一致性雜湊演算法到對應的master節點獲取資料,只有當一個master掛掉之後,才會啟動一個對應的salve節點,充當master

 

  • 需要注意的是:必須要三個或以上主節點,否則在建立叢集時會失敗,並且當存活的主節點數小於總結點的一半時,整個叢集就無法提供服務了。

 7.1.4 連線叢集

任意連線一個節點就進入叢集了

redis-cli -h 172.16.1.74 -c -p 7002

寫入資料

寫入到另一臺節點了

8.python操作redis和redis叢集互動

8.1python操作redis

 1 依賴:
 2 yum -y install zlib zlib-devel
 3 yum -y install bzip2 bzip2-devel
 4 yum -y install ncurses ncurses-devel
 5 yum -y install readline readline-devel
 6 yum -y install openssl openssl-devel
 7 yum -y install openssl-static
 8 yum -y install xz lzma xz-devel
 9 yum -y install sqlite sqlite-devel
10 yum -y install gdbm gdbm-devel
11 yum -y install tk tk-devel
12 yum -y install libffi libffi-devel
13 
14 安裝python3和安裝redis模組:
15 wget https://www.python.org/ftp/python/3.6.7/Python-3.6.7.tgz
16 tar xf Python-3.6.7
17 cd Python-3.6.7
18 ./configure --prefix=/usr/local/python3
19 make && make install
20 ln -s /usr/local/python3/bin/python3 /usr/bin/python3
21 ln -s /usr/local/python3/bin/pip3 /usr/bin/pip3
22 pip3 install redis
安裝python3和redis模組
 1 #!/usr/bin/env python3
 2 import redis
 3 
 4 if __name__ == "__main__":
 5     try:
 6         sr = redis.StrictRedis()
 7         """
 8         #增加key
 9         res = sr.set("name","wsy")
10         print(res)
11         #修改
12         res = sr.set('name','www')
13         #刪除
14         res = sr.delete('name')
15         print(res)
16         #獲取
17         res = sr.get('name')
18         print(res)
19         # del duo ge keys
20         res = sr.delete('user','www')
21         print(res)
22         """
23         # huoqu suoyou jian
24         res = sr.keys()
25         print(res)
26     except Exception as e:
27         print(e)
操作redis

PS:這裡的模組操作方法和redis資料型別的命令基本一致

8.2用redis儲存django的session

安裝包

pip3 install django-redis-sessions

在專案的__init__.py中匯入模組

設定settings.py

設定urls

app名稱為booktest

寫views設定session讀取session

執行,然後去redis檢視

session是通過base64加密的,儲存在資料庫裡是一串加密的字串,我們可以通過線上解碼工具來解碼

Base64線上解碼 http://base64.xpcha.com

 8.3python和叢集互動

 1 安裝redis叢集的模組
 2 pip3 install redis-py-cluster
 3 
 4 程式碼:
 5 #!/usr/bin/env python3
 6 from rediscluster import StrictRedisCluster
 7 
 8 if __name__ == "__main__":
 9    try:
10         startup_nodes = [
11            #連線三個主節點
12            {'host': '172.16.1.74', 'port': '7000'},
13            {'host': '172.16.1.111', 'port': '7003'},
14            {'host': '172.16.1.74', 'port': '7001'},
15         ]
16 
17         src = StrictRedisCluster(startup_nodes=startup_nodes, decode_responses=True)    #例項化這個redis物件,之後就可以呼叫所有裡邊的方法
18         # 插入資料
19         result = src.set('name','wwwwwww')
20         print(result)
21         # 查詢資料
22         name = src.get('name')
23         print(name)
24    except Exception as e:
25         print(e)
python和redis叢集互動

PS:增刪改查資料的方法都是redis命令

 

 

先就到這裡了,更多深入的redis知識已經給出網站自己去挖掘吧。  PS:手指頭瑟瑟發抖...