天天看點

30. Pytnon NoSQL簡介 Redis服務搭建、連接配接池、管道

1.NoSQL簡介

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

雖然NoSQL的流行與火起來才短短幾年的時間,但是不可否認,現在已經開始了第二代運動。盡管早期的堆棧代碼隻能算是一種實驗,然而現在的系統已經更加的成熟、穩定。不過現在也面臨着一個嚴酷的事實:技術越來越成熟——以至于原來很好的NoSQL資料存儲不得不進行重寫,也有少數人認為這就是所謂的2.0版本。該工具可以為大資料建立快速、可擴充的存儲庫。

非關系型資料庫和關系型資料庫的差别:

非關系型資料庫的優勢:

性能NOSQL是基于鍵值對的,可以想象成表中的主鍵和值的對應關系,而且不需要經過SQL層的解析,是以性能非常高。

可擴充性同樣也是因為基于鍵值對,資料之間沒有耦合性,是以非常容易水準擴充。

關系型資料庫的優勢:

複雜查詢可以用SQL語句友善的在一個表以及多個表之間做非常複雜的資料查詢。

事務支援使得對于安全性能很高的資料通路要求得以實作。對于這兩類資料庫,對方的優勢就是自己的弱勢,反之亦然。但是近年來這兩種資料庫都在向着另外一個方向進化。

例如:NOSQL資料庫慢慢開始具備SQL資料庫的一些複雜查詢功能的雛形,比如Couchbase的index以及MONGO的複雜查詢。對于事務的支援也可以用一些系統級的原子操作來實作例如樂觀鎖之類的方法來曲線救國。

SQL資料庫也開始慢慢進化,比如HandlerSocker技術的實作,可以在MYSQL上實作對于SQL層的穿透,用NOSQL的方式通路資料庫,性能可以上可以達到甚至超越NOSQL資料庫。

可擴充性上例如Percona Server,可以實作無中心化的叢集。雖然這兩極都因為各自的弱勢而開始進化出另一極的一些特性,但是這些特性的增加也會消弱其本來具備的優勢,比如Couchbase上的index的增加會逐漸降低資料庫的讀寫性能。是以怎樣建構系統的短期和長期存儲政策,用好他們各自的強項是架構師需要好好考慮的重要問題。

2.redis服務搭建

redis的概念:

redis是一個key-value存儲系統。和Memcached類似,它支援存儲的value類型相對更多,包括string(字元串)、list(連結清單)、set(集合)、zset(sorted set --有序集合)和hash(哈希類型)。這些資料類型都支援push/pop、add/remove及取交集并集和差集及更豐富的操作,而且這些操作都是原子性的。

在此基礎上,redis支援各種不同方式的排序。與memcached一樣,為了保證效率,資料都是緩存在記憶體中。差別的是redis會周期性的把更新的資料寫入磁盤或者把修改操作寫入追加的記錄檔案,并且在此基礎上實作了master-slave(主從)同步。

Redis 是一個高性能的key-value資料庫。 redis的出現,很大程度補償了memcached這類key/value存儲的不足,在部 分場合可以對關系資料庫起到很好的補充作用。它提供了Java,C/C++,C#,PHP,JavaScript,Perl,Object-C,Python,Ruby,Erlang等用戶端,使用很友善。

Redis支援主從同步。資料可以從主伺服器向任意數量的從伺服器上同步,從伺服器可以是關聯其他從伺服器的主伺服器。這使得Redis可執行單層樹複制。存盤可以有意無意的對資料進行寫操作。由于完全實作了釋出/訂閱機制,使得從資料庫在任何地方同步樹時,可訂閱一個頻道并接收主伺服器完整的消息釋出記錄。同步對讀取操作的可擴充性和資料備援很有幫助。

Redis的安裝

Redis一般都是安裝在linux系統中,具體安裝步驟如下:

#另有,安裝redis的用戶端

簡單操作:

redis是以key-value的形式存儲的,是以我們在操作的時候。首先我們将redis所在主機的ip和釋出端口作為參數執行個體化了一個對象r,然後執行set('name','I love you!'),這樣我們就在記憶體中存儲了一個key為shang,值為‘I love you!’的項。我們可以了解為{'shang':'I love you!'},當我們要讀取的之後,keys()就是獲得多有key值。

結果:

I love you!

['shang', 'ajing']

3.redis連接配接池

連接配接池

redis-py使用connection pool(連接配接池)來管理對一個redis server的所有連接配接,避免每次建立、釋放連接配接的開銷。

預設,每個Redis執行個體都會維護一個自己的連接配接池。可以直接建立一個連接配接池,然後作為參數Redis,這樣就可以實作多個Redis執行個體共享一個連接配接池。

Lingxiangxiang

建立一個連接配接池函數,每次使用時候調用就行了:

4.redis管道

管道 

Redis的管道可以打包一次執行多條redis指令,比如将1000條指令一起發給server端,server端處理将資料放在記憶體中,當把1000條指令都處理完成後,server端将所有獲得的資料都傳回給用戶端(client)

redis-py預設在執行每次請求都會建立(連接配接池申請連接配接)和斷開(歸還連接配接池)一次連接配接操作,如果想要在一次請求中指定多個指令,則可以使用pipline實作一次請求指定多個指令,并且預設情況下一次pipline 是原子性操作。減少功耗

redis是一個cs模式的tcp server,使用和http類似的請求響應協定。一個client可以通過一個socket連接配接發起多個請求指令。每個請求指令發出後client通常會阻塞并等待redis服務處理,redis處理完後請求指令後會将結果通過響應封包傳回給client。

基本的通信過程如下:

Client: INCR X

Server: 1

Server: 2

Server: 3

Server: 4

基本上四個指令需要8個tcp封包才能完成。由于通信會有網絡延遲,假如從client和server之間的包傳輸時間需要0.125秒。那麼上面的四個指令8個封包至少會需要1秒才能完成。這樣即使redis每秒能處理100個指令,而我們的client也隻能一秒鐘發出四個指令。這顯示沒有充分利用 redis的處理能力。除了可以利用mget,mset 之類的單條指令處理多個key的指令外我們還可以利用pipeline的方式從client打包多條指令一起發出,不需要等待單條指令的響應傳回,而redis服務端會處理完多條指令後會将多條指令的處理結果打包到一起傳回給用戶端。

通信過程如下:

假設不會因為tcp封包過長而被拆分。可能兩個tcp封包就能完成四條指令,client可以将四個指令放到一個tcp封包一起發送,server則可以将四條指令的處理結果放到一個tcp封包傳回。通過pipeline方式當有大批量的操作時候。我們可以節省很多原來浪費在網絡延遲的時間。需要注意到是用 pipeline方式打包指令發送,redis必須在處理完所有指令前先緩存起所有指令的處理結果。打包的指令越多,緩存消耗記憶體也越多,是以并是不是打包的指令越多越好,具體多少合适需要根據具體情況測試。

withpipe time is : 28000

withoutpipe time is : 253000

本文轉自 聽丶飛鳥說 51CTO部落格,原文連結:http://blog.51cto.com/286577399/2044081