1. 程式人生 > >redis系統性總結筆記

redis系統性總結筆記

一、Redis入門介紹

1.1 redis概述

1.1.1  概念

1)

Redis:REmote DIctionary Server(遠端字典伺服器)

2)

是完全開源免費的,用C語言編寫的,遵守BSD協議,

是一個高效能的(key/value)分散式記憶體資料庫,基於記憶體執行

並支援持久化的NoSQL資料庫,是當前最熱門的NoSql資料庫之一,

也被人們稱為資料結構伺服器

3)

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

3.1)  Redis支援資料的持久化,可以將記憶體中的資料保持在磁碟中,重啟的時候可以再次載入進行使用;

3.2)  Redis不僅僅支援簡單的key-value型別的資料,同時還提供list,set,zset,hash等資料結構的儲存

3.3)  Redis支援資料的備份,即master-slave模式的資料備份

1.1.2功能

1) 記憶體儲存和持久化:redis支援非同步將記憶體中的資料寫到硬碟上,同時不影響繼續服務;

2) 取最新N個數據的操作,如:可以將最新的10條評論的ID放在Redis的List集合裡面;

3) 模擬類似於HttpSession這種需要設定過期時間的功能;

4) 釋出、訂閱訊息系統

5) 定時器、計數器

1.1.3去哪下

http://redis.io/

http://www.redis.cn/

1.3.4操作

1)  資料型別、基本操作和配置

2)  持久化和複製,RDB/AOF

3)  事務的控制

4)  複製

......

1.2 VMWare+VMTools

VMWare虛擬機器的安裝

CentOS或者RedHad5的安裝

如何檢視自己的linux是32位還是64位? getconf LONG_BIT返回是多少就是幾位

假如出現了不支援虛擬化的問題怎麼辦?

我的筆記本cpu是64位的,作業系統也是64位的,問題應該如虛擬機器右下角提示所說,

是“宿主機BIOS設定中的硬體虛擬化被禁用了。”

需要開啟筆記本BIOS中的IVT對虛擬化的支援。

找到選單“Security”–“System Security”,

將Virtualization Technology(VTx)和Virtualization Technology DirectedI/O(VTd)設定為 Enabled。

儲存並退出BIOS設定,重啟電腦,

VMTools的安裝

設定共享目錄

上述環境都OK後開始進行Redis的伺服器安裝配置

1.3 Redis的安裝

1.3.1Windows版安裝

Window 下安裝

下載地址:https://github.com/dmajkic/redis/downloads

下載到的Redis支援32bit和64bit。根據自己實際情況選擇,將64bit的內容cp到自定義碟符安裝目錄取名redis。 如 C:\reids

開啟一個cmd視窗 使用cd命令切換目錄到 C:\redis 執行 redis-server.exe redis.conf 。

如果想方便的話,可以把redis的路徑加到系統的環境變數裡,這樣就省得再輸路徑了,後面的那個redis.conf可以省略,

如果省略,會啟用預設的。輸入之後,會顯示如下介面:

這時候另啟一個cmd視窗,原來的不要關閉,不然就無法訪問服務端了。

切換到redis目錄下執行 redis-cli.exe -h 127.0.0.1 -p 6379 。

設定鍵值對 set myKey abc

取出鍵值對 get myKey

1.3.2重要提示

由於企業裡面做Redis開發,99%都是Linux版的運用和安裝,

幾乎不會涉及到Windows版,上一步的講解只是為了知識的完整性,

Windows版不作為重點,同學可以下去自己玩,企業實戰就認一個版:Linux

1.3.3Linux版安裝

1) 下載獲得redis-3.2.8.tar.gz後將它放入我們的Linux目錄/usr/local

2)  /usr/local目錄下,使用root使用者解壓命令:tar -zxvf redis-3.2.8.tar.gz

3)  解壓完成後出現資料夾:redis-3.2.8

4)  進入目錄:cd redis-3.2.8

5)  在redis-3.2.8目錄下執行使用使用root使用者執行make命令

執行make命令時故意出現的錯誤解析:

安裝gcc

二次make

jemalloc/jemalloc.h:沒有那個檔案或目錄,-- 執行make distclean之後再make

Redis Test(可以不用執行) 

下載TCL的網址:

http://www.linuxfromscratch.org/blfs/view/cvs/general/tcl.html

安裝TCL

6)  如果make完成後繼續使用root使用者執行make install

注意:

如果不使用root使用者解壓和安裝,會出現許可權不足,出現這種情況,需要執行

清理,然後重新使用root使用者安裝

7) 檢視預設安裝目錄:usr/local/bin

redis-benchmark:效能測試工具,可以在自己本子執行,看看自己本子效能如何

redis-check-aof:修復有問題的AOF檔案,rdb和aof後面講

redis-check-dump:修復有問題的dump.rdb檔案

redis-cli:客戶端,操作入口

redis-sentinel:redis叢集使用

redis-server:Redis伺服器啟動命令

8) 啟動

修改redis.conf檔案將裡面的daemonize no 改成 yes,讓服務在後臺啟動

將預設的redis.conf拷貝到自己定義好的一個路徑下,比如/myconf

啟動 redis-server /myconf/myconf.conf

連通測試 ping

/usr/local/bin目錄下執行redis-server,執行拷貝出存放了自定義conf檔案目錄下的redis.conf檔案

9) 關閉

單例項關閉:redis-cli  shutdown

多例項關閉,指定埠關閉:redis-cli  -p  6379  shutdown

1.3.4Redis啟動後雜項基礎知識講解

1) 單程序

a)單程序模型來處理客戶端的請求。對讀寫等事件的響應是通過對epoll函式的包裝來做到的。Redis的實際處理速度完全依靠主程序的執行效率

b)epoll是Linux核心為處理大批量檔案描述符而作了改進的epoll,是Linux下多路複用IO介面select/poll的增強版本,它能顯著提高程式在大量併發連線中只有少量活躍的情況下的系統CPU利用率。

2) 預設16個數據庫,類似陣列下表從零開始,初始預設使用零號庫

設定資料庫的數量,預設資料庫為0,可以使用SELECT <dbid>命令在連線上指定資料庫id

  databases 16

3)  select命令切換資料庫

4)  dbsize檢視當前資料庫的key的數量

5)  flushdb:清空當前庫

6)  Flushall;通殺全部庫

7)  統一密碼管理,16個庫都是同樣密碼,要麼都OK要麼一個也連線不上

8)  Redis索引都是從零開始

9)  為什麼預設埠是6379

二、Redis解析配置檔案redis.conf

2.1它在哪

解壓目錄

2.2 units單位

# Note on units: when memory size is needed, it is possible to specify

# it in the usual form of 1k 5GB 4M and so forth:

#

# 1k => 1000 bytes

# 1kb => 1024 bytes

# 1m => 1000000 bytes

# 1mb => 1024*1024 bytes

# 1g => 1000000000 bytes

# 1gb => 1024*1024*1024 bytes

#

# units are case insensitive so 1GB 1Gb 1gB are all the same.

2.3 INCLUDES包含

# include /path/to/local.conf

# include /path/to/other.conf

2.4 GENERAL通用

daemonize

pidfile

port

tcp-backlog

設定tcp的backlog,backlog其實是一個連線佇列,backlog佇列總和=未完成三次握手佇列 + 已經完成三次握手佇列。

在高併發環境下你需要一個高backlog值來避免慢客戶端連線問題。注意Linux核心會將這個值減小到/proc/sys/net/core/somaxconn的值,所以需要確認增大somaxconn和tcp_max_syn_backlog兩個值

來達到想要的效果

timeout

bind

tcp-keepalive

loglevel

logfile

syslog-enabled

syslog-ident

syslog-facility

指定syslog裝置,值可以是USER或LOCAL0-LOCAL7

給大家演示cat  /var/log/messages | more

databases

2.5 SNAPSHOTTING快照

Save

save 秒鐘 寫操作次數

禁用

RDB是整個記憶體的壓縮過的Snapshot,RDB的資料結構,可以配置複合的快照觸發條件,

預設

是1分鐘內改了1萬次,

或5分鐘內改了10次,

或15分鐘內改了1次。

stop-writes-on-bgsave-error

如果配置成no,表示你不在乎資料不一致或者有其他的手段發現和控制

rdbcompression

rdbcompression:對於儲存到磁碟中的快照,可以設定是否進行壓縮儲存。如果是的話,redis會採用

LZF演算法進行壓縮。如果你不想消耗CPU來進行壓縮的話,可以設定為關閉此功能

rdbchecksum

rdbchecksum:在儲存快照後,還可以讓redis使用CRC64演算法來進行資料校驗,但是這樣做會增加大約

10%的效能消耗,如果希望獲取到最大的效能提升,可以關閉此功能

dbfilename

dir

2.6  REPLICATION複製

2.7 SECURITY安全

訪問密碼的檢視、設定和取消

2.8 LIMITS限制

maxclients

設定redis同時可以與多少個客戶端進行連線。預設情況下為10000個客戶端。當你

無法設定程序檔案控制代碼限制時,redis會設定為當前的檔案控制代碼限制值減去32,因為redis會為自

身內部處理邏輯留一些控制代碼出來。如果達到了此限制,redis則會拒絕新的連線請求,並且向這

些連線請求方發出“max number of clients reached”以作迴應。

maxmemory

設定redis可以使用的記憶體量。一旦到達記憶體使用上限,redis將會試圖移除內部資料,移除規則可以通過maxmemory-policy來指定。如果redis無法根據移除規則來移除記憶體中的資料,或者設定了“不允許移除”,

那麼redis則會針對那些需要申請記憶體的指令返回錯誤資訊,比如SET、LPUSH等。

但是對於無記憶體申請的指令,仍然會正常響應,比如GET等。如果你的redis是主redis(說明你的redis有從redis),那麼在設定記憶體使用上限時,需要在系統中留出一些記憶體空間給同步佇列快取,只有在你設定的是“不移除”的情況下,才不用考慮這個因素

maxmemory-policy

 (1)volatile-lru:使用LRU演算法移除key,只對設定了過期時間的鍵

(2)allkeys-lru:使用LRU演算法移除key

(3)volatile-random:在過期集合中移除隨機的key,只對設定了過期時間的鍵

(4)allkeys-random:移除隨機的key

(5)volatile-ttl:移除那些TTL值最小的key,即那些最近要過期的key

(6)noeviction:不進行移除。針對寫操作,只是返回錯誤資訊

maxmemory-samples

設定樣本數量,LRU演算法和最小TTL演算法都並非是精確的演算法,而是估算值,所以你可以設定樣本的大小,

redis預設會檢查這麼多個key並選擇其中LRU的那個

2.9 APPEND ONLY MODE追加

appendonly yes/no

appendfilename

appendfsync

always:同步持久化 每次發生資料變更會被立即記錄到磁碟  效能較差但資料完整性比較好

everysec:出廠預設推薦,非同步操作,每秒記錄   如果一秒內宕機,有資料丟失

no-appendfsync-on-rewrite

重寫時是否可以運用Appendfsync,用預設no即可,保證資料安全性。

auto-aof-rewrite-min-size

設定重寫的基準值

auto-aof-rewrite-percentage

設定重寫的基準值

2.10常見配置

引數說明

redis.conf 配置項說明如下:

1. Redis預設不是以守護程序的方式執行,可以通過該配置項修改,使用yes啟用守護程序

  daemonize no

2. 當Redis以守護程序方式執行時,Redis預設會把pid寫入/var/run/redis.pid檔案,可以通過pidfile指定

  pidfile /var/run/redis.pid

3. 指定Redis監聽埠,預設埠為6379,作者在自己的一篇博文中解釋了為什麼選用6379作為預設埠,因為6379在手機按鍵上MERZ對應的號碼,而MERZ取自義大利歌女Alessia Merz的名字

  port 6379

4. 繫結的主機地址

  bind 127.0.0.1

5.當 客戶端閒置多長時間後關閉連線,如果指定為0,表示關閉該功能

  timeout 300

6. 指定日誌記錄級別,Redis總共支援四個級別:debug、verbose、notice、warning,預設為verbose

  loglevel verbose

7. 日誌記錄方式,預設為標準輸出,如果配置Redis為守護程序方式執行,而這裡又配置為日誌記錄方式為標準輸出,則日誌將會發送給/dev/null

  logfile stdout

8. 設定資料庫的數量,預設資料庫為0,可以使用SELECT <dbid>命令在連線上指定資料庫id

  databases 16

9. 指定在多長時間內,有多少次更新操作,就將資料同步到資料檔案,可以多個條件配合

  save <seconds> <changes>

  Redis預設配置檔案中提供了三個條件:

  save  900  1

  save  300  10

  save  60   10000

  分別表示900秒(15分鐘)內有1個更改,300秒(5分鐘)內有10個更改以及60秒內有10000個更改。

10. 指定儲存至本地資料庫時是否壓縮資料,預設為yes,Redis採用LZF壓縮,如果為了節省CPU時間,可以關閉該選項,但會導致資料庫檔案變的巨大

  rdbcompression yes

11. 指定本地資料庫檔名,預設值為dump.rdb

  dbfilename dump.rdb

12. 指定本地資料庫存放目錄

  dir ./

13. 設定當本機為slav服務時,設定master服務的IP地址及埠,在Redis啟動時,它會自動從master進行資料同步

  slaveof <masterip> <masterport>

14. 當master服務設定了密碼保護時,slav服務連線master的密碼

  masterauth <master-password>

15. 設定Redis連線密碼,如果配置了連線密碼,客戶端在連線Redis時需要通過AUTH <password>命令提供密碼,預設關閉

  requirepass foobared

16. 設定同一時間最大客戶端連線數,預設無限制,Redis可以同時開啟的客戶端連線數為Redis程序可以開啟的最大檔案描述符數,如果設定 maxclients 0,表示不作限制。當客戶端連線數到達限制時,Redis會關閉新的連線並向客戶端返回max number of clients reached錯誤資訊

  maxclients 128

17. 指定Redis最大記憶體限制,Redis在啟動時會把資料載入到記憶體中,達到最大記憶體後,Redis會先嚐試清除已到期或即將到期的Key,當此方法處理 後,仍然到達最大記憶體設定,將無法再進行寫入操作,但仍然可以進行讀取操作。Redis新的vm機制,會把Key存放記憶體,Value會存放在swap區

  maxmemory <bytes>

18. 指定是否在每次更新操作後進行日誌記錄,Redis在預設情況下是非同步的把資料寫入磁碟,如果不開啟,可能會在斷電時導致一段時間內的資料丟失。因為 redis本身同步資料檔案是按上面save條件來同步的,所以有的資料會在一段時間內只存在於記憶體中。預設為no

  appendonly no

19. 指定更新日誌檔名,預設為appendonly.aof

   appendfilename appendonly.aof

20. 指定更新日誌條件,共有3個可選值: 

  no:表示等作業系統進行資料快取同步到磁碟(快) 

  always:表示每次更新操作後手動呼叫fsync()將資料寫到磁碟(慢,安全) 

  everysec:表示每秒同步一次(折衷,預設值)

  appendfsync everysec

21. 指定是否啟用虛擬記憶體機制,預設值為no,簡單的介紹一下,VM機制將資料分頁存放,由Redis將訪問量較少的頁即冷資料swap到磁碟上,訪問多的頁面由磁碟自動換出到記憶體中  

vm-enabled no

22. 虛擬記憶體檔案路徑,預設值為/tmp/redis.swap,不可多個Redis例項共享

   vm-swap-file /tmp/redis.swap

23. 將所有大於vm-max-memory的資料存入虛擬記憶體,無論vm-max-memory設定多小,所有索引資料都是記憶體儲存的(Redis的索引資料 就是keys),也就是說,當vm-max-memory設定為0的時候,其實是所有value都存在於磁碟。預設值為0

   vm-max-memory 0

24. Redis swap檔案分成了很多的page,一個物件可以儲存在多個page上面,但一個page上不能被多個物件共享,vm-page-size是要根據儲存的 資料大小來設定的,作者建議如果儲存很多小物件,page大小最好設定為32或者64bytes;如果儲存很大大物件,則可以使用更大的page,如果不 確定,就使用預設值

   vm-page-size 32

25. 設定swap檔案中的page數量,由於頁表(一種表示頁面空閒或使用的bitmap)是在放在記憶體中的,,在磁碟上每8個pages將消耗1byte的記憶體。

   vm-pages 134217728

26. 設定訪問swap檔案的執行緒數,最好不要超過機器的核數,如果設定為0,那麼所有對swap檔案的操作都是序列的,可能會造成比較長時間的延遲。預設值為4

   vm-max-threads 4

27. 設定在向客戶端應答時,是否把較小的包合併為一個包傳送,預設為開啟

  glueoutputbuf  yes

28. 指定在超過一定的數量或者最大的元素超過某一臨界值時,採用一種特殊的雜湊演算法

  hash-max-zipmap-entries 64

  hash-max-zipmap-value 512

29. 指定是否啟用重置雜湊,預設為開啟(後面在介紹Redis的雜湊演算法時具體介紹)

  activerehashing yes

30. 指定包含其它的配置檔案,可以在同一主機上多個Redis例項之間使用同一份配置檔案,而同時各個例項又擁有自己的特定配置檔案

  include /path/to/local.conf

三、概念原理

3.1 NoSql概述

3.1.1網際網路時代背景下 大機遇,為什麼用nosql

3.1.1.1單機MySQL的美好年代

在90年代以及現在的小網站,一個網站的訪問量一般都不大,用單個數據庫完全可以輕鬆應付。

更多的都是靜態網頁,動態互動型別的網站不多。

上述架構下,我們來看看資料儲存的瓶頸是什麼?

1.資料量的總大小 一個機器放不下時

2.資料的索引(B+ Tree)一個機器的記憶體放不下時

3.訪問量(讀寫混合)一個例項不能承受

 如果滿足了上述1 or 3個,進化......

3.1.1.2Memcached(快取)+MySQL+垂直拆分

後來,隨著訪問量的上升,幾乎大部分使用MySQL架構的網站在資料庫上都開始出現了效能問題,web程式不再僅僅專注在功能上,同時也在追求效能。程式設計師們開始大量的使用快取技術來緩解資料庫的壓力,優化資料庫的結構和索引。開始比較流行的是通過檔案快取來緩解資料庫壓力,但是當訪問量繼續增大的時候,多臺web機器通過檔案快取不能共享,大量的小檔案快取也帶了了比較高的IO壓力。在這個時候,Memcached就自然的成為一個非常時尚的技術產品。

Memcached作為一個獨立的分散式的快取伺服器,為多個web伺服器提供了一個共享的高效能快取服務,在Memcached伺服器上,又發展了根據hash演算法來進行多臺Memcached快取服務的擴充套件,然後又出現了一致性hash來解決增加或減少快取伺服器導致重新hash帶來的大量快取失效的弊端

3.1.1.3Mysql主從讀寫分離

由於資料庫的寫入壓力增加,Memcached只能緩解資料庫的讀取壓力。讀寫集中在一個數據庫上讓資料庫不堪重負,大部分網站開始使用主從複製技術來達到讀寫分離,以提高讀寫效能和讀庫的可擴充套件性。

Mysql的master-slave模式成為這個時候的網站標配了。

3.1.1.4分表分庫+水平拆分+mysql叢集

在Memcached的快取記憶體,MySQL的主從複製,讀寫分離的基礎之上,這時MySQL主庫的寫壓力開始出現瓶頸,而資料量的持續猛增,由於MyISAM使用表鎖,在高併發下會出現嚴重的鎖問題,大量的高併發MySQL應用開始使用InnoDB引擎代替MyISAM。

同時,開始流行使用分表分庫來緩解寫壓力和資料增長的擴充套件問題。這個時候,分表分庫成了一個熱門技術,是面試的熱門問題也是業界討論的熱門技術問題。也就在這個時候,MySQL推出了還不太穩定的表分割槽,這也給技術實力一般的公司帶來了希望。雖然MySQL推出了MySQL Cluster叢集,但效能也不能很好滿足網際網路的要求,只是在高可靠性上提供了非常大的保證。

3.1.1.5MySQL的擴充套件性瓶頸

MySQL資料庫也經常儲存一些大文字欄位,導致資料庫表非常的大,在做資料庫恢復的時候就導致非常的慢,不容易快速恢復資料庫。比如1000萬4KB大小的文字就接近40GB的大小,如果能把這些資料從MySQL省去,MySQL將變得非常的小。關係資料庫很強大,但是它並不能很好的應付所有的應用場景。MySQL的擴充套件性差(需要複雜的技術來實現),大資料下IO壓力大,表結構更改困難,正是當前使用MySQL的開發人員面臨的問題。

3.1.1.6今天是什麼樣子

3.1.1.7為什麼用NoSQL

為什麼使用NoSQL ?

今天我們可以通過第三方平臺(如:Google,Facebook等)可以很容易的訪問和抓取資料。使用者的個人資訊,社交網路,地理位置,使用者生成的資料和使用者操作日誌已經成倍的增加。我們如果要對這些使用者資料進行挖掘,SQL資料庫已經不適合這些應用了, NoSQL資料庫的發展也卻能很好的處理這些大的資料。

3.1.2NoSql是什麼

NoSQL(NoSQL = Not Only SQL ),意即“不僅僅是SQL”,

泛指非關係型的資料庫。隨著網際網路web2.0網站的興起,傳統的關係資料庫在應付web2.0網站,特別是超大規模和高併發的SNS型別的web2.0純動態網站已經顯得力不從心,暴露了很多難以克服的問題,而非關係型的資料庫則由於其本身的特點得到了非常迅速的發展。NoSQL資料庫的產生就是為了解決大規模資料集合多重資料種類帶來的挑戰,尤其是大資料應用難題,包括超大規模資料的儲存。

(例如谷歌或Facebook每天為他們的使用者收集萬億位元的資料)。這些型別的資料儲存不需要固定的模式,無需多餘操作就可以橫向擴充套件

3.1.3NoSql能完成什麼功能

3.1.3.1易擴充套件

NoSQL資料庫種類繁多,但是一個共同的特點都是去掉關係資料庫的關係型特性。

資料之間無關係,這樣就非常容易擴充套件。也無形之間,在架構的層面上帶來了可擴充套件的能力。

3.1.3.2 大資料量高效能

NoSQL資料庫都具有非常高的讀寫效能,尤其在大資料量下,同樣表現優秀。

這得益於它的無關係性,資料庫的結構簡單。

一般MySQL使用Query Cache,每次表的更新Cache就失效,是一種大粒度的Cache,

在針對web2.0的互動頻繁的應用,Cache效能不高。而NoSQL的Cache是記錄級的,

是一種細粒度的Cache,所以NoSQL在這個層面上來說就要效能高很多了

3.1.3.3多樣靈活的資料模型

NoSQL無需事先為要儲存的資料建立欄位,隨時可以儲存自定義的資料格式。而在關係資料庫裡,

增刪欄位是一件非常麻煩的事情。如果是非常大資料量的表,增加欄位簡直就是一個噩夢

3.1.3.4傳統RDBMS  vs  NOSQL

RDBMS

- 高度組織化結構化資料

- 結構化查詢語言(SQL)

- 資料和關係都儲存在單獨的表中。

- 資料操縱語言,資料定義語言

- 嚴格的一致性

- 基礎事務

NoSQL

- 代表著不僅僅是SQL

- 沒有宣告性查詢語言

- 沒有預定義的模式

-鍵 - 值對儲存,列儲存,文件儲存,圖形資料庫

- 最終一致性,而非ACID屬性

- 非結構化和不可預知的資料

- CAP定理【後面講】

- 高效能,高可用性和可伸縮性

3.1.4去哪下

Redis

https://redis.io

memcache

        http://memcached.org/

Mongdb

        https://www.mongodb.com/

3.1.5怎麼玩

1.KV

2.Cache

3.Persistence

4……

3.2 3V + 3高

3.2.1大資料時代的3V

海量Volume

多樣Variety

實時Velocity

3.2.2網際網路需求的3高

高併發

高可擴

高效能

3.2當下的NoSQL經典應用

3.2.1當下的應用是sql和nosql一起使用

3.2.2阿里巴巴中文站商品資訊如何存放

3.2.2.1看看阿里巴巴中文網站首頁以女裝/女包包為例

1.       架構發展歷程

演變過程

5

5代架構使命

和我們相關的,多資料來源多資料型別的儲存問題

1商品基本資訊

名稱、價格,出廠日期,生產廠商等

關係型資料庫:mysql/oracle目前淘寶在去O化(也即拿掉Oracle),

注意,淘寶內部用的Mysql是裡面的大牛自己改造過的

為什麼去IOE

 2008年,王堅加盟阿里巴巴成為集團首席架構師,即現在的首席技術官。這位前微軟亞洲研究院常務副院長被馬雲定位為:將幫助阿里巴巴集團建立世界級的技術團隊,並負責集團技術架構以及基礎技術平臺搭建。

在加入阿里後,帶著技術基因和學者風範的王堅就在阿里巴巴集團提出了被稱為“去IOE”(在IT建設過程中,去除IBM小型機、Oracle資料庫及EMC儲存裝置)的想法,並開始把雲端計算的本質,植入阿里IT基因。

王堅這樣概括“去IOE”運動和阿里雲之間的關係:“去IOE”徹底改變了阿里集團IT架構的基礎,是阿里擁抱雲端計算,產出計算服務的基礎。“去IOE”的本質是分佈化,讓隨處可以買到的Commodity PC架構成為可能,使雲端計算能夠落地的首要條件。

2商品描述、詳情、評價資訊(多文字類)

多文字資訊描述類,IO讀寫效能變差

使用文件資料庫MongDB中

3商品的圖片

商品圖片展現類放在分散式的檔案系統中:

淘寶自己的TFS

Google的GFS

Hadoop的HDFS

4商品的關鍵字

搜尋引擎,淘寶內用

ISearch

5商品的波段性的熱點高頻資訊

記憶體資料庫

tair、Redis、Memcache

6商品的交易、價格計算、積分累計

外部系統,外部第3方支付介面

支付寶

3.3總結大型網際網路應用(大資料、高併發、多樣資料型別)的難點和解決方案

3.3.1難點

資料型別多樣性

資料來源多樣性和變化重構

資料來源改造而資料服務平臺不需要大面積重構

3.3.2解決辦法

3.3.2.1 概念:EAI和統一資料平臺服務層是什麼

3.3.2.2  淘寶UDSL

既然EAI和統一資料平臺服務層那麼流行,那麼淘寶是怎麼實現的呢?淘寶是怎麼實現的。阿里、淘寶幹了什麼?

UDSL總圖
1)   對映
2)   API
3)   熱點快取
4)   ….

3.4 NoSQL資料模型簡介

3.4.1電商客戶、訂單、訂購、地址模型 vs 關係型資料庫和非關係型資料庫

3.4.1.1傳統的關係型資料庫你如何設計?

ER圖(1:1/1:N/N:N,主外來鍵等常見)

3.4.1.2nosql你如何設計

什麼是BSON

BSON()是一種類json的一種二進位制形式的儲存格式,簡稱Binary JSON,

它和JSON一樣,支援內嵌的文件物件和陣列物件

用BSon畫出構建的資料模型

{

 "customer":{

   "id":1136,

   "name":"Z3",

   "billingAddress":[{"city":"beijing"}],

   "orders":[

    {

      "id":17,

      "customerId":1136,

      "orderItems":[{"productId":27,"price":77.5,"productName":"thinking in java"}],

      "shippingAddress":[{"city":"beijing"}]

      "orderPayment":[{"ccinfo":"111-222-333","txnid":"asdfadcd334","billingAddress":{"city":"beijing"}}],

      }

    ]

  }

}

3.4.1.3兩者對比,問題和難點

1)為什麼上述的情況可以用聚合模型來處理

1.1高併發的操作是不太建議有關聯查詢的,網際網路公司用冗餘資料來避免關聯查詢

1.2分散式事務是支援不了太多的併發的

如果按照我們新設計的BSon,查詢起來會很簡單

3.4.2聚合模型

3.4.2.1KV鍵值
3.4.2.2bson
3.4.2.3列族

顧名思義,是按列儲存資料的。最大的特點是方便儲存結構化和半結構化資料,方便做資料壓縮,對針對某一列或者某幾列的查詢有非常大的IO優勢。

3.4.2.4圖形

3.5 NoSQL資料庫的四大分類

3.5.1 KV鍵值:典型介紹

新浪:BerkeleyDB+redis

美團:redis+tair

阿里、百度:memcache+redis

3.5.2 文件型資料庫(bson格式比較多):典型介紹

CouchDB

MongoDB

MongoDB 是一個基於分散式檔案儲存的資料庫。由 C++ 語言編寫。旨在為 WEB 應用提供可擴充套件的高效能資料儲存解決方案。

MongoDB 是一個介於關係資料庫和非關係資料庫之間的產品,是非關係資料庫當中功能最豐富,最像關係資料庫的。

3.5.3  列儲存資料庫

Cassandra, HBase

分散式檔案系統

3.5.4  圖關係資料庫

它不是放圖形的,放的是關係比如:朋友圈社交網路、廣告推薦系統

社交網路,推薦系統等。專注於構建關係圖譜

Neo4J, InfoGrid

3.5.5  四者對比

3.6 在分散式資料庫中CAP原理CAP+BASE

3.6.1傳統的ACID分別是什麼

A (Atomicity) 原子性

C (Consistency) 一致性

I (Isolation) 獨立性

D (Durability) 永續性

關係型資料庫遵循ACID規則

事務在英文中是transaction,和現實世界中的交易很類似,它有如下四個特性:

1、A (Atomicity) 原子性

原子性很容易理解,也就是說事務裡的所有操作要麼全部做完,要麼都不做,事務成功的條件是事務裡的所有操作都成功,只要有一個操作失敗,整個事務就失敗,需要回滾。比如銀行轉賬,從A賬戶轉100元至B賬戶,分為兩個步驟:1)從A賬戶取100元;2)存入100元至B賬戶。這兩步要麼一起完成,要麼一起不完成,如果只完成第一步,第二步失敗,錢會莫名其妙少了100元。

2、C (Consistency) 一致性

一致性也比較容易理解,也就是說資料庫要一直處於一致的狀態,事務的執行不會改變資料庫原本的一致性約束。

3、I (Isolation) 獨立性

所謂的獨立性是指併發的事務之間不會互相影響,如果一個事務要訪問的資料正在被另外一個事務修改,只要另外一個事務未提交,它所訪問的資料就不受未提交事務的影響。比如現有有個交易是從A賬戶轉100元至B賬戶,在這個交易還未完成的情況下,如果此時B查詢自己的賬戶,是看不到新增加的100元的

4、D (Durability) 永續性

永續性是指一旦事務提交後,它所做的修改將會永久的儲存在資料庫上,即使出現宕機也不會丟失。

3.6.2 CAP

C:Consistency(強一致性)

A:Availability(可用性)

P:Partition tolerance(分割槽容錯性)

3.6.3 CAP的3進2

CAP理論就是說在分散式儲存系統中,最多隻能實現上面的兩點。

而由於當前的網路硬體肯定會出現延遲丟包等問題,所以

分割槽容忍性是我們必須需要實現的。

所以我們只能在一致性和可用性之間進行權衡,沒有NoSQL系統能同時保證這三點。

=======================================================================================================================

C:強一致性 A:高可用性 P:分散式容忍性

 CA 傳統Oracle資料庫

 AP 大多數網站架構的選擇

 CP Redis、Mongodb

 注意:分散式架構的時候必須做出取捨。

一致性和可用性之間取一個平衡。多餘大多數web應用,其實並不需要強一致性。

因此犧牲C換取P,這是目前分散式資料庫產品的方向

=======================================================================================================================

一致性與可用性的決擇

對於web2.0網站來說,關係資料庫的很多主要特性卻往往無用武之地

資料庫事務一致性需求 

  很多web實時系統並不要求嚴格的資料庫事務,對讀一致性的要求很低, 有些場合對寫一致性要求並不高。允許實現最終一致性。

資料庫的寫實時性和讀實時性需求

  對關係資料庫來說,插入一條資料之後立刻查詢,是肯定可以讀出來這條資料的,但是對於很多web應用來說,並不要求這麼高的實時性,比方說發一條訊息之 後,過幾秒乃至十幾秒之後,我的訂閱者才看到這條動態是完全可以接受的。

對複雜的SQL查詢,特別是多表關聯查詢的需求 

  任何大資料量的web系統,都非常忌諱多個大表的關聯查詢,以及複雜的資料分析型別的報表查詢,特別是SNS型別的網站,從需求以及產品設計角 度,就避免了這種情況的產生。往往更多的只是單表的主鍵查詢,以及單表的簡單條件分頁查詢,SQL的功能被極大的弱化了。

3.6.4  經典CAP圖

3.6.5 BASE

BASE就是為了解決關係資料庫強一致性引起的問題而引起的可用性降低而提出的解決方案。

BASE其實是下面三個術語的縮寫:

    基本可用(Basically Available)

    軟狀態(Soft state)

    最終一致(Eventually consistent)

它的思想是通過讓系統放鬆對某一時刻資料一致性的要求來換取系統整體伸縮性和效能上改觀。為什麼這麼說呢,緣由就在於大型系統往往由於地域分佈和極高效能的要求,不可能採用分散式事務來完成這些指標,要想獲得這些指標,我們必須採用另外一種方式來完成,這裡BASE就是解決這個問題的辦法

3.6.6 分散式+叢集簡介

分散式系統

分散式系統(distributed system)

 由多臺計算機和通訊的軟體元件通過計算機網路連線(本地網路或廣域網)組成。分散式系統是建立在網路之上的軟體系統。正是因為軟體的特性,所以分散式系統具有高度的內聚性和透明性。因此,網路和分散式系統之間的區別更多的在於高層軟體(特別是作業系統),而不是硬體。分散式系統可以應用在在不同的平臺上如:Pc、工作站、區域網和廣域網上等。

簡單來講:

1分散式:不同的多臺伺服器上面部署不同的服務模組(工程),他們之間通過Rpc/Rmi之間通訊和呼叫,對外提供服務和組內協作。

2叢集:不同的多臺伺服器上面部署相同的服務模組,通過分散式排程軟體進行統一的排程,對外提供服務和訪問。

四、Redis資料型別

4.1             Redis的五大資料型別

4.1.1     string(字串)

String(字串)

string是redis最基本的型別,你可以理解成與Memcached一模一樣的型別,一個key對應一個value。

string型別是二進位制安全的。意思是redis的string可以包含任何資料。比如jpg圖片或者序列化的物件 。

string型別是Redis最基本的資料型別,一個redis中字串value最多可以是512M

4.1.2     hash(雜湊,類似java裡的Map)

Hash(雜湊)

Redis hash 是一個鍵值對集合。

Redis hash是一個string型別的field和value的對映表,hash特別適合用於儲存物件。

類似Java裡面的Map<String,Object>

4.1.3     list(列表)

List(列表)

Redis 列表是簡單的字串列表,按照插入順序排序。你可以新增一個元素導列表的頭部(左邊)或者尾部(右邊)。

它的底層實際是個連結串列

4.1.4     set(集合)

Set(集合)

Redis的Set是string型別的無序集合。它是通過HashTable實現實現的,

4.1.5     zset(sorted set:有序集合)

zset(sorted set:有序集合)

Redis zset 和 set 一樣也是string型別元素的集合,且不允許重複的成員。

不同的是每個元素都會關聯一個double型別的分數。

redis正是通過分數來為集合中的成員進行從小到大的排序。zset的成員是唯一的,但分數(score)卻可以重複。

4.2             哪裡去獲得redis常見資料型別操作命令

http://redisdoc.com/

4.3             Redis 鍵(key)

exists key的名字,判斷某個key是否存在

move key db   --->當前庫就沒有了,被移除了

expire key 秒鐘:為給定的key設定過期時間

ttl key 檢視還有多少秒過期,-1表示永不過期,-2表示已過期

type key 檢視你的key是什麼型別

4.4             Redis字串(String) ---單值單value

set/get/del/append/strlen

Incr/decr/incrby/decrby,一定要是數字才能進行加減

getrange/setrange

setex(set with expire)鍵秒值/setnx(set if not exist)

mset/mget/msetnx

getset(先get再set)

4.5             Redis列表(List)-- 單值多value

lpush/rpush/lrange

lpop/rpop

lindex,按照索引下標獲得元素(從上到下)

llen

lrem key 刪N個value

ltrim key 開始index 結束index,擷取指定範圍的值後再賦值給key

rpoplpush 源列表 目的列表

lset key index value

linsert key  before/after 值1 值2

效能總結

它是一個字串連結串列,left、right都可以插入新增;

如果鍵不存在,建立新的連結串列;

如果鍵已存在,新增內容;

如果值全移除,對應的鍵也就消失了。

連結串列的操作無論是頭和尾效率都極高,但假如是對中間元素進行操作,效率就很慘淡了。

4.6             Redis集合(Set)-- 單值多value

sadd/smembers/sismember

scard,獲取集合裡面的元素個數

srem key value 刪除集合中元素

srandmember key 某個整數(隨機出幾個數)

spop key 隨機出棧

smove key1 key2 在key1裡某個值      作用是將key1裡的某個值賦給key2

數學集合類

差集:sdiff

交集:sinter

並集:sunion

4.7             Redis雜湊(Hash)-- KV模式不變,但V是一個鍵值對

hset/hget/hmset/hmget/hgetall/hdel

hlen

hexists key 在key裡面的某個值的key

hkeys/hvals

hincrby/hincrbyfloat

hsetnx

4.8             Redis有序集合Zset(sortedset)

在set基礎上,加一個score值。

之前set是k1 v1 v2 v3,

現在zset是k1 score1 v1 score2 v2

zadd/zrange

zrangebyscore key 開始score 結束score

withscores  (  不包含

limit 作用是返回限制  limit 開始下標步 多少步

zrem key 某score下對應的value值,作用是刪除元素

zcard/zcount key score區間/zrank key values值,作用是獲得下標值/zscore key 對應值,獲得分數

zcard/zcount key score區間/zrank key values值,作用是獲得下標值/zscore key 對應值,獲得分數

zrevrange

zrevrangebyscore  key 結束score 開始score

五redis的持久化

5.1             RDB(Redis DataBase)

5.1.1     RDB概念

在指定的時間間隔內將記憶體中的資料集快照寫入磁碟,

也就是行話講的Snapshot快照,它恢復時是將快照檔案直接讀到記憶體裡

Redis會單獨建立(fork)一個子程序來進行持久化,會先將資料寫入到

一個臨時檔案中,待持久化過程都結束了,再用這個臨時檔案替換上次持久化好的檔案。

整個過程中,主程序是不進行任何IO操作的,這就確保了極高的效能

如果需要進行大規模資料的恢復,且對於資料恢復的完整性不是非常敏感,那RDB方

式要比AOF方式更加的高效。RDB的缺點是最後一次持久化後的資料可能丟失。

5.1.2     Fork

fork的作用是複製一個與當前程序一樣的程序。新程序的所有資料(變數、環境變數、程式計數器等)

數值都和原程序一致,但是是一個全新的程序,並作為原程序的子程序

5.1.3     rdb 儲存的是dump.rdb檔案

rdb 儲存的是dump.rdb檔案

檔名稱可以配置,比如配置為dump6379.rdb

5.1.4     配置位置

參見redis配置檔案解讀之 SNAPSHOTTING快照

5.1.5     如何觸發RDB快照

1)       配置檔案中預設的快照配置

冷拷貝後重新使用

可以cp dump.rdb dump_new.rdb

2)       命令save或者是bgsave

      Save:save時只管儲存,其它不管,全部阻塞

      BGSAVE:Redis會在後臺非同步進行快照操作,快照同時還可以響應客戶端請求。可以通過lastsave命令獲取最後一次成功執行快照的時間

3)       執行flushall命令,也會產生dump.rdb檔案,但裡面是空的,無意義

5.1.6     如何恢復

將備份檔案 (dump.rdb) 移動到 redis 安裝目錄並啟動服務即可

CONFIG GET dir獲取目錄,需要放在dir配置的目錄下

5.1.7     優勢

適合大規模的資料恢復

對資料完整性和一致性要求不高

5.1.8     劣勢

在一定間隔時間做一次備份,所以如果redis意外down掉的話,就

會丟失最後一次快照後的所有修改

fork的時候,記憶體中的資料被克隆了一份,大致2倍的膨脹性需要考慮

5.1.9     如何停止

動態所有停止RDB儲存規則的方法:redis-cli config set save ""

5.1.10              小總結

5.2             AOF(Append OnlyFile)

既然已經有了RDB為什麼還有會AOFRDBAOF哪個先存在?

5.2.1     AOF概念

以日誌的形式來記錄每個寫操作,將Redis執行過的所有寫指令記錄下來(讀操作不記錄),

只許追加檔案但不可以改寫檔案,redis啟動之初會讀取該檔案重新構建資料,換言之,redis

重啟的話就根據日誌檔案的內容將寫指令從前到後執行一次以完成資料的恢復工作

5.2.2     Aof儲存的是appendonly.aof檔案

5.2.3     配置位置

參見redis配置檔案解讀之APPEND ONLY MODE追加

5.2.4     AOF啟動/修復/恢復

5.2.4.1    正常恢復

啟動:設定Yes:修改預設的appendonly no,改為yes

將有資料的aof檔案複製一份儲存到對應目錄(config  get  dir)

恢復:重啟redis然後重新載入

5.2.4.2    異常恢復

啟動:設定Yes:修改預設的appendonly no,改為yes

備份被寫壞的AOF檔案

修復:redis-check-aof --fix進行修復

恢復:重啟redis然後重新載入

5.2.5     rewrite

5.2.5.1    是什麼

AOF採用檔案追加方式,檔案會越來越大為避免出現此種情況,新增了重寫機制,

當AOF檔案的大小超過所設定的閾值時,Redis就會啟動AOF檔案的內容壓縮,

只保留可以恢復資料的最小指令集.可以使用命令bgrewriteaof

高斯公式: 1 + 2 + 3 + 4 + … + 98 + 99 + 100

壓縮 + 優化

5.2.5.2    重寫原理

AOF檔案持續增長而過大時,會fork出一條新程序來將檔案重寫(也是先寫臨時檔案最後再rename),

遍歷新程序的記憶體中資料,每條記錄有一條的Set語句。重寫aof檔案的操作,並沒有讀取舊的aof檔案,

而是將整個記憶體中的資料庫內容用命令的方式重寫了一個新的aof檔案,這點和快照有點類似

5.2.5.3    觸發機制

Redis會記錄上次重寫時的AOF大小,預設配置是當AOF檔案大小是上次rewrite後大小的一倍且檔案大於64M時觸發

大公司一般設定在3G ~ 5G

5.2.6     優勢

每秒同步:appendfsync everysec    非同步操作,每秒記錄   如果一秒內宕機,有資料丟失

不同步:appendfsync no   從不同步

5.2.7     劣勢

相同資料集的資料而言aof檔案要遠大於rdb檔案,恢復速度慢於rdb

aof執行效率要慢於rdb,每秒同步策略效率較好,不同步效率和rdb相同

5.2.8     小總結

5.3             總結(Which one)

5.3.1     選擇

RDB持久化方式能夠在指定的時間間隔能對你的資料進行快照儲存

AOF持久化方式記錄每次對伺服器寫的操作,當伺服器重啟的時候會重新執行這些

命令來恢復原始的資料,AOF命令以redis協議追加儲存每次寫的操作到檔案末尾.

Redis還能對AOF檔案進行後臺重寫,使得AOF檔案的體積不至於過大

只做快取:如果你只希望你的資料在伺服器執行的時候存在,你也可以不使用任何持久化方式.

5.3.2     同時開啟兩種持久化方式

在這種情況下,當redis重啟的時候會優先載入AOF檔案來恢復原始的資料,

因為在通常情況下AOF檔案儲存的資料集要比RDB檔案儲存的資料集要完整.

RDB的資料不實時,同時使用兩者時伺服器重啟也只會找AOF檔案。那要不要只使用AOF呢?

作者建議不要,因為RDB更適合用於備份資料庫(AOF在不斷變化不好備份),

快速重啟,而且不會有AOF可能潛在的bug,留著作為一個萬一的手段。

5.3.3     效能建議

因為RDB檔案只用作後備用途,建議只在Slave上持久化RDB檔案,而且只要15分鐘備份一次就夠了,只保留save 900 1這條規則。

如果Enalbe AOF,好處是在最惡劣情況下也只會丟失不超過兩秒資料,啟動指令碼較簡單隻load自己的AOF檔案就可以了。代價一是帶來了持續的IO,二是AOF rewrite的最後將rewrite過程中產生的新資料寫到新檔案造成的阻塞幾乎是不可避免的。只要硬碟許可,應該儘量減少AOF rewrite的頻率,AOF重寫的基礎大小預設值64M太小了,可以設到5G以上。預設超過原大小100%大小時重寫可以改到適當的數值。

如果不Enable AOF ,僅靠Master-Slave Replication 實現高可用性也可以。能省掉一大筆IO也減少了rewrite時帶來的系統波動。代價是如果Master/Slave同時倒掉,會丟失十幾分鐘的資料,啟動指令碼也要比較兩個Master/Slave中的RDB檔案,載入較新的那個。新浪微博就選用了這種架構

六 Redis的複製(Master/Slave)

6.1              概念

行話:也就是我們所說的主從複製,主機資料更新後根據配置和策略,

自動同步到備機的master/slaver機制,Master以寫為主,Slave以讀為主

6.2              功能

讀寫分離

容災恢復

6.3              如何操作

6.3.1     配置

1)  配從(庫)不配主(庫)

2)從庫配置:slaveof 主庫IP 主庫埠

每次與master斷開之後,都需要重新連線,除非你配置進redis.conf檔案

info replication

3)修改配置檔案細節操作

拷貝多個redis.conf檔案

開啟daemonize yes

pid檔名字

指定埠

log檔名字

dump.rdb名字

6.3.2     常用3招

6.3.2.1       一主二僕

如何init

 一個Master兩個Slave

 日誌檢視:主機日誌、備機日誌、info replication

 主從問題演示

1 切入點問題?slave1、slave2是從頭開始複製還是從切入點開始複製?比如從k4進來,那之前的123是否也可以複製

2 從機是否可以寫?set可否?

3 主機shutdown後情況如何?從機是上位還是原地待命

4 主機又回來了後,主機新增記錄,從機還能否順利複製?

5 其中一臺從機down後情況如何?依照原有它能跟上大部隊嗎?

6.3.2.2       薪火相傳

1.       上一個Slave可以是下一個slave的Master,Slave同樣可以接收其他slaves的連線和同步請求,那麼該slave作為了鏈條中下一個的master,可以有效減輕master的寫壓力

2.中途變更轉向:會清除之前的資料,重新建立拷貝最新的

  slaveof 新主庫IP 新主庫埠

6.3.2.3       反客為主(手動控制)

SLAVEOF no one

使當前資料庫停止與其他資料庫的同步,轉成主資料庫

6.1複製原理

slave啟動成功連線到master後會傳送一個sync命令

Master接到命令啟動後臺的存檔程序,同時收集所有接收到的用於修改資料集命令,

在後臺程序執行完畢之後,master將傳送整個資料檔案到slave,以完成一次完全同步

全量複製:而slave服務在接收到資料庫檔案資料後,將其存檔並載入到記憶體中。

增量複製:Master繼續將新的所有收集到的修改命令依次傳給slave,完成同步

但是隻要是重新連線master,一次完全同步(全量複製)將被自動執行

6.4              哨兵模式(sentinel)

6.4.1     概