国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Redis-py官方文檔翻譯

Alfred / 1980人閱讀

摘要:采取兩種實(shí)現(xiàn)命令其一類盡量堅(jiān)持官方語法,但是以下除外沒有實(shí)現(xiàn),應(yīng)該是線程安全的原因。線程安全性是線程安全的。由于線程安全原因,不提供實(shí)現(xiàn),因?yàn)樗鼤?huì)導(dǎo)致數(shù)據(jù)庫的切換。

官網(wǎng):https://github.com/andymccurd...
當(dāng)前版本:2.10.5
注:這不是完整翻譯,只提取了關(guān)鍵信息。省略了部分內(nèi)容,如lua腳本支持。

pip install redis
pip install hiredis(解析器,可選。windows下好像不行。)

>>> import redis
>>> r = redis.StrictRedis(host="localhost", port=6379, db=0)
>>> r.set("foo", "bar")
True
>>> r.get("foo")
"bar"

redis-py采取兩種client class實(shí)現(xiàn)redis命令:
其一、StrictRedis類盡量堅(jiān)持官方語法,但是以下除外:

SELECT: 沒有實(shí)現(xiàn),應(yīng)該是線程安全的原因。

DEL: 由于del是python語法關(guān)鍵字,所用delete來代替。

CONFIG GET|SET: 分開用 config_get or config_set來代替

MULTI/EXEC: 事務(wù)作為Pipeline類的其中一部分的實(shí)現(xiàn)。Pipeline默認(rèn)保證了MULTI,EXEC聲明。但是你可以指定transaction=False來禁用這一行為。

SUBSCRIBE/LISTEN:PubSub作為一個(gè)獨(dú)立的類來實(shí)現(xiàn)發(fā)布訂閱機(jī)制。

SCAN/SSCAN/HSCAN/ZSCAN:每個(gè)命令都對(duì)應(yīng)一個(gè)等價(jià)的迭代器方法scan_iter/sscan_iter/hscan_iter/zscan_iter methods for this behavior.

其二、Redis類是StrictRedis的子類,提供redis-py版本向后的兼容性。

關(guān)于StrictRedis與Redis的區(qū)別:(官方推薦使用StrictRedis.)
以下幾個(gè)方法在StrictRedis和Redis類中的參數(shù)順序不同。
LREM: Order of "num" and "value" arguments reversed such that "num" can provide a default value of zero.
在Redis類中是這樣的:
lrem(self, name, value, num=0)
在StrictRedis類中是這樣的:
lrem(self, name, count, value)

ZADD: Redis specifies the "score" argument before "value". These were swapped accidentally when being implemented and not discovered until after people were already using it. The Redis class expects *args in the form of: name1, score1, name2, score2, ...
在Redis類中是這樣的:
redis.zadd("my-key", "name1", 1.1, "name2", 2.2, name3=3.3, name4=4.4)
在StrictRedis中是這樣的:
redis.zadd("my-key", 1.1, "name1", 2.2, "name2", name3=3.3, name4=4.4)

SETEX: Order of "time" and "value" arguments reversed.
在Redis類中是這樣的:
setex(self, name, value, time)
而在StrictRedis中是這樣的:
setex(self, name, time, value)

連接池
>>> pool = redis.ConnectionPool(host="localhost", port=6379, db=0)
>>> r = redis.Redis(connection_pool=pool)

Connections:redis-py提供兩種類型的連接:基于TCP端口的,基于Unix socket文件的(需要redis服務(wù)器開啟配置)。

>>> r = redis.Redis(unix_socket_path="/tmp/redis.sock")

如果你需要,自定義連接類,需要告知連接池。

>>> pool = redis.ConnectionPool(connection_class=YourConnectionClass,
                                your_arg="...", ...)

釋放連接回到連接池:可以使用Redis類的reset()方法,或者使用with上下文管理語法。

解析器:
解析器控制如何解析Redis-server的響應(yīng)內(nèi)容,redis-py提供兩種方式的解析器類支持:PythonParser和HiredisParser(需要多帶帶安裝)。它優(yōu)先選用HiredisParser,如果不存在,則選用PythonParser. Hiredis是redis核心團(tuán)隊(duì)開發(fā)的一個(gè)高性能c庫,能夠提高10x的解析速度。

響應(yīng)回調(diào):
The client class使用一系列的callbacks來完成響應(yīng)到對(duì)應(yīng)python類型的映射。這些響應(yīng)回調(diào),定義在 Redis client class中的RESPONSE_CALLBACKS字典中。你可以使用set_response_callback 方法來添加自定義回調(diào)類。這個(gè)方法接受兩個(gè)參數(shù):一個(gè)命令名字,一個(gè)回調(diào)類?;卣{(diào)類接受至少一個(gè)參數(shù):響應(yīng)內(nèi)容,關(guān)鍵字參數(shù)作為命令調(diào)用時(shí)的參數(shù)。

線程安全性:

Redis client instances是線程安全的。由于線程安全原因,不提供select實(shí)現(xiàn),因?yàn)樗鼤?huì)導(dǎo)致數(shù)據(jù)庫的切換。
在不同線程間傳遞PubSub or Pipeline對(duì)象也是不安全的。

Pipelines

Pipelines是Redis類的一個(gè)子類,支持緩存多個(gè)命令,然后作為單個(gè)請(qǐng)求發(fā)送。通過減少TCP請(qǐng)求次數(shù)來達(dá)到提供性能的目的。

>>> r = redis.Redis(...)
>>> r.set("bing", "baz")
>>> # Use the pipeline() method to create a pipeline instance
>>> pipe = r.pipeline()
>>> # The following SET commands are buffered
>>> pipe.set("foo", "bar")
>>> pipe.get("bing")
>>> # the EXECUTE call sends all buffered commands to the server, returning
>>> # a list of responses, one for each command.
>>> pipe.execute()
[True, "baz"]

Pipelines的實(shí)現(xiàn)采用流式API,故而你可以采用以下鏈?zhǔn)秸{(diào)用的方式:

>>> pipe.set("foo", "bar").sadd("faz", "baz").incr("auto_number").execute()
[True, True, 6]

Pipelines默認(rèn)以原子性(事務(wù))的形式執(zhí)行所有緩存的命令,你也可以禁用這一行為:

>>> pipe = r.pipeline(transaction=False)

WATCH命令提供了在事務(wù)之前檢測一個(gè)或多個(gè)key值的變化。一旦在事務(wù)執(zhí)行之前,某個(gè)值發(fā)生了變化,那么事務(wù)將被取消然后拋出WatchError 異常。
利用watch我們可以實(shí)現(xiàn)client-side incr命令:

>>> with r.pipeline() as pipe:
...     while 1:
...         try:
...             # put a WATCH on the key that holds our sequence value
...             pipe.watch("OUR-SEQUENCE-KEY")
...             # after WATCHing, the pipeline is put into immediate execution
...             # mode until we tell it to start buffering commands again.
...             # this allows us to get the current value of our sequence
...             current_value = pipe.get("OUR-SEQUENCE-KEY")
...             next_value = int(current_value) + 1
...             # now we can put the pipeline back into buffered mode with MULTI
...             pipe.multi()
...             pipe.set("OUR-SEQUENCE-KEY", next_value)
...             # and finally, execute the pipeline (the set command)
...             pipe.execute()
...             # if a WatchError wasn"t raised during execution, everything
...             # we just did happened atomically.
...             break
...        except WatchError:
...             # another client must have changed "OUR-SEQUENCE-KEY" between
...             # the time we started WATCHing it and the pipeline"s execution.
...             # our best bet is to just retry.
...             continue

不過你可以使用transaction方法來簡化這一操作:它包含handling and retrying watch errors的樣板代碼。第一參數(shù)為callable(這個(gè)callable只能接受一個(gè)Pipeline參數(shù)),及多個(gè)需要被WATCH的keys

>>> def client_side_incr(pipe):
...     current_value = pipe.get("OUR-SEQUENCE-KEY")
...     next_value = int(current_value) + 1
...     pipe.multi()
...     pipe.set("OUR-SEQUENCE-KEY", next_value)
>>>
>>> r.transaction(client_side_incr, "OUR-SEQUENCE-KEY")
[True]
Publish / Subscribe

PubSub對(duì)象subscribes to channels and listens for new messages。

>>> r = redis.StrictRedis(...)
>>> p = r.pubsub()

>>> p.subscribe("my-first-channel", "my-second-channel", ...)
>>> p.psubscribe("my-*", ...)

>>> p.get_message()
{"pattern": None, "type": "subscribe", "channel": "my-second-channel", "data": 1L}
>>> p.get_message()
{"pattern": None, "type": "subscribe", "channel": "my-first-channel", "data": 2L}
>>> p.get_message()
{"pattern": None, "type": "psubscribe", "channel": "my-*", "data": 3L}

通過PubSub獲取消息時(shí)返回的是一個(gè)字典,字典key有如下幾個(gè):
type:其中一個(gè), "subscribe", "unsubscribe", "psubscribe", "punsubscribe", "message", "pmessage"
channel: The channel [un]subscribed to or the channel a message was published to
pattern: The pattern that matched a published message"s channel. Will be None in all cases except for "pmessage" types.
data: The message data. With [un]subscribe messages, this value will be the number of channels and patterns the connection is currently subscribed to. With [p]message messages, this value will be the actual published message.
現(xiàn)在來發(fā)布消息:

# the publish method returns the number matching channel and pattern
# subscriptions. "my-first-channel" matches both the "my-first-channel"
# subscription and the "my-*" pattern subscription, so this message will
# be delivered to 2 channels/patterns
>>> r.publish("my-first-channel", "some data")
2
>>> p.get_message()
{"channel": "my-first-channel", "data": "some data", "pattern": None, "type": "message"}
>>> p.get_message()
{"channel": "my-first-channel", "data": "some data", "pattern": "my-*", "type": "pmessage"}

取消訂閱:如果沒有傳遞任何參數(shù),那么這個(gè)PubSub訂閱的所有的channels or patterns都會(huì)被取消。

>>> p.unsubscribe()
>>> p.punsubscribe("my-*")
>>> p.get_message()
{"channel": "my-second-channel", "data": 2L, "pattern": None, "type": "unsubscribe"}
>>> p.get_message()
{"channel": "my-first-channel", "data": 1L, "pattern": None, "type": "unsubscribe"}
>>> p.get_message()
{"channel": "my-*", "data": 0L, "pattern": None, "type": "punsubscribe"}
回調(diào)的方式處理發(fā)布的消息

redis-py還允許你通過回調(diào)的方式處理發(fā)布的消息。
Message handlers接受一個(gè)參數(shù),the message,是一個(gè)字典對(duì)象。just like the examples above.
以回調(diào)形式訂閱:subscribe接受關(guān)鍵字參數(shù),鍵為channels or patterns,值為回調(diào)函數(shù)。

>>> def my_handler(message):
...     print "MY HANDLER: ", message["data"]
>>> p.subscribe(**{"my-channel": my_handler})

在你注冊(cè)了回調(diào)處理的情況下, get_message()會(huì)返回None。

默認(rèn)情況下除了發(fā)布消息之外,還會(huì)傳遞 subscribe/unsubscribe成功的確認(rèn)消息,如果你不想接收它們:ignore_subscribe_messages=True

>>> p = r.pubsub(ignore_subscribe_messages=True)
>>> p.subscribe("my-channel")
>>> p.get_message()  # hides the subscribe message and returns None
>>> r.publish("my-channel")
1
>>> p.get_message()
{"channel": "my-channel", "data": "my data", "pattern": None, "type": "message"}
三種讀取消息的方式

第一種:無限循環(huán)通過PubSub對(duì)象的get_message()讀取消息

>>> while True:
>>>     message = p.get_message()
>>>     if message:
>>>         # do something with the message
>>>     time.sleep(0.001)  # be nice to the system :)

第二種,通過阻塞方法listen()來讀?。簆.listen()返回一個(gè)generator,阻塞直到有消息可獲取。

>>> for message in p.listen():
...     # do something with the message

第三種,開啟一個(gè)事件循環(huán)線程pubsub.run_in_thread()方法 creates a new thread and starts the event loop. 并返回線程對(duì)象。
但是需要注意的是:如果你沒有注冊(cè)消息處理函數(shù),那么調(diào)用run_in_thread()將會(huì)拋出異常redis.exceptions.PubSubError

>>> p.subscribe(**{"my-channel": my_handler})
>>> thread = p.run_in_thread(sleep_time=0.001)
# the event loop is now running in the background processing messages
# when it"s time to shut it down...
>>> thread.stop()
關(guān)于字符編碼:

默認(rèn)情況下,publish的消息會(huì)被編碼,當(dāng)你獲取消息時(shí)得到的是編碼后的字節(jié),如果你需要它自動(dòng)解碼,創(chuàng)建Redis client實(shí)例時(shí)需要指定decode_responses=True,(譯者注:不建議使用該選項(xiàng),因?yàn)楫?dāng)存在pickle序列化的值時(shí),client.get(key)時(shí)會(huì)出現(xiàn)解碼失敗的錯(cuò)誤UnicodeDecodeError)

關(guān)閉釋放資源:

PubSub.close() method to shutdown the connection.

>>> p = r.pubsub()
>>> ...
>>> p.close()
LUA Scripting支持:

略。

Sentinel support與節(jié)點(diǎn)發(fā)現(xiàn):

Redis Sentinel用于發(fā)現(xiàn)Redis節(jié)點(diǎn)。請(qǐng)確保至少一個(gè)Sentinel daemon 進(jìn)程在運(yùn)行。
你可以使用Sentinel connection to discover the master and slaves network addresses:

>>> from redis.sentinel import Sentinel
>>> sentinel = Sentinel([("localhost", 26379)], socket_timeout=0.1)
>>> sentinel.discover_master("mymaster")
("127.0.0.1", 6379)
>>> sentinel.discover_slaves("mymaster")
[("127.0.0.1", 6380)]

>>> master = sentinel.master_for("mymaster", socket_timeout=0.1)
>>> slave = sentinel.slave_for("mymaster", socket_timeout=0.1)
>>> master.set("foo", "bar")
>>> slave.get("foo")
"bar"

上面的master and slave對(duì)象就是一個(gè)普通的StrictRedis對(duì)象實(shí)例。如果Sentinel配置了連接池的話,它們還會(huì)使用這個(gè)連接池。
可能拋出的異常:MasterNotFoundError ,SlaveNotFoundError 它們都是ConnectionError的子類

Scan Iterators

Redis 2.8之后有了*SCAN命令。redis-py also exposes the following methods that return Python iterators for convenience: scan_iter, hscan_iter, sscan_iter and zscan_iter.

>>> for key, value in (("A", "1"), ("B", "2"), ("C", "3")):
...     r.set(key, value)
>>> for key in r.scan_iter():
...     print key, r.get(key)
A 1
B 2
C 3

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/38234.html

相關(guān)文章

  • 區(qū)分Python的redis客戶端:hiredis、hiredis-py、redis-py

    摘要:由于學(xué)習(xí)實(shí)戰(zhàn)用的是,需要按的客戶端庫。提供兩個(gè)類,和。還寫了一個(gè)版本的即。使用可以使得客戶端解析服務(wù)端響應(yīng)內(nèi)容的速度提升倍。而且當(dāng)執(zhí)行檢索多條數(shù)據(jù)時(shí)性能更顯著,如等。 由于學(xué)習(xí)《Redis實(shí)戰(zhàn)》用的是Python,需要按Python的redis客戶端庫。被幾個(gè)庫搞得有點(diǎn)暈,在此區(qū)分一下。 區(qū)分hiredis、hiredis-py、redis-py redis官網(wǎng)Github:https...

    Hanks10100 評(píng)論0 收藏0
  • Django-緩存

    摘要:自帶了一個(gè)健壯的緩存系統(tǒng)來保存動(dòng)態(tài)頁面,避免每次請(qǐng)求都重新計(jì)算。緩存中的和方法是很常見的。盡量放在第一個(gè)繼承的類設(shè)置過期時(shí)間根據(jù)自己需求加緩存。目前這個(gè)緩存使用的是內(nèi)存。 概述:對(duì)于中等流量的網(wǎng)站來說,盡可能的減少開銷是非常必要的。緩存數(shù)據(jù)就是為了保存那些需要很多計(jì)算資源的結(jié)果,這樣的話就不必在下次重復(fù)消耗計(jì)算資源。獲取數(shù)據(jù)的數(shù)據(jù)的時(shí)候就是去緩存中拿,拿到了直接返回,沒拿到就去數(shù)據(jù)庫中...

    aervon 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<