python操作redis

來源:互聯網
上載者:User

標籤:python   redis   nosql   

非關係型資料庫和關係型資料庫的差別:

非關係型資料庫的優勢:

1. 效能NOSQL是基於索引值對的,可以想象成表中的主鍵和值的對應關係,而且不需要經過SQL層的解析,所以效能非常高。

2. 可擴充性同樣也是因為基於索引值對,資料之間沒有耦合性,所以非常容易水平擴充。

關係型資料庫的優勢:

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

2. 事務支援使得對於安全效能很高的資料訪問要求得以實現。對於這兩類資料庫,對方的優勢就是自己的弱勢,反之亦然。但是近年來這兩種資料庫都在向著另外一個方向進化。

例如:NOSQL資料庫慢慢開始具備SQL資料庫的一些複雜查詢功能的雛形,比如Couchbase的index以及MONGO的複雜查詢。對於事務的支援也可以用一些系統級的原子操作來實現例如樂觀鎖之類的方法來曲線救國。SQL資料庫也開始慢慢進化,比如HandlerSocker技術的實現,可以在MYSQL上實現對於SQL層的穿透,用NOSQL的方式訪問資料庫,效能可以上可以達到甚至超越NOSQL資料庫。可擴充性上例如Percona Server,可以實現無中心化的叢集。雖然這兩極都因為各自的弱勢而開始進化出另一極的一些特性,但是這些特性的增加也會消弱其本來具備的優勢,比如Couchbase上的index的增加會逐步降低資料庫的讀寫效能。所以怎樣構建系統的短期和長期儲存策略,用好他們各自的強項是架構師需要好好考慮的重要問題。

python操作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系統中,具體安裝步驟如下:

#cd /usr/local/src

#wget http://download.redis.io/releases/redis-3.0.1.tar.gz 

#tar xzf redis-3.0.1.tar.gz 

#cd redis-3.0.1 

#make

#src/redis-server &

檢查redis是否正常啟動

Ps –ef |grep redis

Netstat –lnp |grep 6379

python安裝redis的模組

Pip install redis

redis是以key-value的形式儲存的,所以我們在操作的時候。首先我們將redis所在主機的ip和發布連接埠作為參數執行個體化了一個對象r,然後執行set('hello','world'),這樣我們就在記憶體中儲存了一個key為hello,值為‘world’的項。我們可以理解為{'hello':'world'},當我們要讀取的之後,keys()就是獲得多有key值。

例子:

import redis

r = redis.Redis(host="192.168.1.1", port=6379)

r.set("hello", "world")

print(r.get("hello"))

print(r.keys())

# print(dir(r))

2.串連池

redis-py使用connection pool來管理對一個redis server的所有串連,避免每次建立、釋放串連的開銷。預設,每個Redis執行個體都會維護一個自己的串連池。可以直接建立一個串連池,然後作為參數Redis,這樣就可以實現多個Redis執行個體共用一個串連池

例子:

import redis

pool = redis.ConnectionPool(host="192.168.1.1")

r = redis.Redis(connection_pool=pool)

r.set("python", "study")

print(r.get("python"))

管道

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

redis是一個cs模式的tcp server,使用和http類似的請求響應協議。一個client可以通過一個socket串連發起多個請求命令。每個請求命令發出後client通常會阻塞並等待redis服務處理,redis處理完後請求命令後會將結果通過響應報文返回給client。基本的通訊過程如下:

Client: INCR X

Server: 1

Client: INCR X

Server: 2

Client: INCR X

Server: 3

Client: INCR X

Server: 4

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

Client: INCR X

Client: INCR X

Client: INCR X

Client: INCR X

Server: 1

Server: 2

Server: 3

Server: 4

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

例子:

import datetime

import redis

def withpipe(r):

    pipe = r.pipeline(transaction=True)

    for i in xrange(1, 1000):

        key = "test1" +str(i)

        value = "test1" + str(i)

        pipe.set(key, value)

    pipe.execute()

def withoutpipe(r):

    # pipe = r.pipeline(transaction=True)

    for i in xrange(1, 1000):

        key = "test1" + str(i)

        value = "test1" + str(i)

        r.set(key, value)

if __name__ == "__main__":

    pool = redis.ConnectionPool(host="192.168.1.1", port=6379, db=0)

    r1 = redis.Redis(connection_pool=pool)

    r2 = redis.Redis(connection_pool=pool)

    start = datetime.datetime.now()

    # print(start)

    withpipe(r1)

    end = datetime.datetime.now()

    # print((end-start).microseconds)

    # print(end-start)

    t_time = (end - start).microseconds

    print("withpipe time is : {0}".format(t_time))

    start = datetime.datetime.now()

    withoutpipe(r2)

    end = datetime.datetime.now()

    t_time = (end - start).microseconds

    print("withoutpipe time is : {0}".format(t_time))

結果:

withpipe time is : 28000

withoutpipe time is : 253000


python操作redis

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.