㈠ php 用 redis做隊列 運行過程是什麼樣的
Reids是一個比較高級的開源key-value存儲系統,採用ANSI C實現。其與memcached類似,但是支持持久化數據存儲入隊操作
復制代碼 代碼如下:
<?php
$redis = new Redis();
$redis->connect('127.0.0.1',6379);
while(True){
try{
$value = 'value_'.date('Y-m-d H:i:s');
$redis->LPUSH('key1',$value);
sleep(rand()%3);
echo $value."\n";
}catch(Exception $e){
echo $e->getMessage()."\n";
}
}
?>
出隊操作
復制代碼 代碼如下:
<?php
$redis = new Redis();
$redis->pconnect('127.0.0.1',6379);
while(True){
try{
echo $redis->LPOP('key1')."\n";
}catch(Exception $e){
echo $e->getMessage()."\n";
}
sleep(rand()%3);
}?>
如何使用Redis 做隊列操作
Reids是一個比較高級的開源key-value存儲系統,採用ANSI C實現。其與memcached類似,但是支持持久化數據存儲,同時value支持多種類型:字元串 (同memcached中的value),列表 ,集合 (Set),有序集合 (OrderSet)和Hash 。所有的值類型均支持原子操作,如列表中追加彈出元素,集合中插入移除元素等。Rdids的數據大部分位於內存中,其讀寫效率非常高,其提供AOF(追加 式操作記錄文件)和DUMP(定期數據備份)兩種持久化方式。Redis支持自定義的VM(虛擬內存)機制,當數據容量超過內存時,可以將部分Value 存儲到文件中。同時Redis支持Master-Slave機制,可以進行數據復制。
可以把Redis的list結構當隊列來用.
從上面Redis的場景和作用來說,對於我們現在的開發活動,究竟能把Redis引入在那些場景,而不是把這么好的東東演變成「為了使用Redis,而Redis」的慘烈局面呢?當然,具體問題具體分析,這個真的很重要哈。
緩存?分布式緩存?
隊列?分布式隊列?
某些系統應用(例如,電信、銀行和大型互聯網應用等)都會使用到,當然,現在大行其道的memcache就是很好的證明;但從某一方面來說,memcache是否能把兩張囊括其中,而且能做到更好(沒有實際的應用過,所以只是拋出)。但從Redis身上,我就能感覺到,Redis,就能把隊列和緩存兩張都囊括其中,而且都不會產生並發環境下的困擾,因為Redis中的操作都是原子操作來著。
至於評論兩者的孰好孰壞就免了,存在就是理由,選擇適合的就是最好的。
下面開始玩玩Redis中的隊列(分布式)設計YY吧,請大蝦們多多指點。
狀況場景:
現在的項目,都是部署在多個伺服器,或者多個IP上,而且前台經由F5分發,所以用戶的請求究竟落在那一台的伺服器上,是無法確定的。對於項目中,有一秒殺設計,剛開始沒有考慮到這種部署,同時也是使用最容易處理的方式,直接給資料庫表鎖行記錄(Oracle上的)。可以說,對於不同的應用部署,而只有一台資料庫伺服器來說,很「輕松」的就解決了這個並發的問題。所以現在考慮一下,是不是挪到應用上,避免資料庫伺服器也摻雜到業務上。
比如,現在有2台應用伺服器,1台資料庫伺服器。想法是,把Redis部署在資料庫伺服器上,兩台伺服器在操作並發緩存或者隊列時,先從Redis伺服器上,取得在兩台應用伺服器的代理對象,再做入列出列的操作。
看代碼實現(PHP)
入隊列操作文件 list_push.php
復制代碼 代碼如下:
<?php
$redis = getRedisInstance();//從Redis伺服器拿到redis實例$redis->connect('Redis伺服器IP', 6379);
while (true) {
$redis->lPush('list1', 'A_'.date('Y-m-d H:i:s'));sleep(rand()%3);
}
?>
執行# php list_push.php &
出隊列操作 list_pop.php文件
復制代碼 代碼如下:
<?php
$redis = getRedisInstance();//從Redis伺服器拿到redis實例$redis->pconnect('Redis伺服器IP', 6379);
while(true) {
try {
var_export( $redis->blPop('list1', 10) );} catch(Exception $e) {
//echo $e;
}
}
實現方法(python)
1.入隊列(write.py)
復制代碼 代碼如下:
#!/usr/bin/env python
import time
from redis import Redis
redis = Redis(host='127.0.0.1', port=6379)while True:
now = time.strftime("%Y/%m/%d %H:%M:%S")
redis.lpush('test_queue', now)
time.sleep(1)
2.出隊列(read.py)
復制代碼 代碼如下:
#!/usr/bin/env python
import sys
from redis import Redis
redis = Redis(host='127.0.0.1', port=6379)while True:
res = redis.rpop('test_queue')
if res == None:
pass
else:
print str(res)
㈡ 如何使用Redis 做隊列操作
redis設計用來做緩存的,但是由於它自身的某種特性使得它可以用來做消息隊列,它有幾個阻塞式的API可以使用,正是這些阻塞式的API讓其有能力做消息隊列;
另外,做消息隊列的其他特性例如FIFO(先入先出)也很容易實現,只需要一個list對象從頭取數據,從尾部塞數據即可;
redis能做消息隊列還得益於其list對象blpop brpop介面以及Pub/Sub(發布/訂閱)的某些介面,它們都是阻塞版的,所以可以用來做消息隊列。
㈢ php使用redis的有序集合zset實現延遲隊列
延遲隊列就是個帶延遲功能的消息隊列,相對於普通隊列,它可以在指定時間消費掉消息。
我們通過redis的有序集合zset來實現簡單的延遲隊列,將消息數據序列化,作為zset的value,把消息處理時間作為score,每次通過zRangeByScore獲取一條消息進行處理。
然後,我們寫一個php腳本,用來處理隊列中的任務。
㈣ redis隊列什麼意思
Redis隊列功能介紹
List
常用命令:
Blpop刪除,並獲得該列表中的第一元素,或阻塞,直到有一個可用
Brpop刪除,並獲得該列表中的最後一個元素,或阻塞,直到有一個可用
Brpoplpush
Lindex獲取一個元素,通過其索引列表
Linsert在列表中的另一個元素之前或之後插入一個元素
Llen獲得隊列(List)的長度
Lpop從隊列的左邊出隊一個元素
Lpush從隊列的左邊入隊一個或多個元素
Lpushx當隊列存在時,從隊到左邊入隊一個元素
Lrange從列表中獲取指定返回的元素
Lrem從列表中刪除元素
Lset設置隊列裡面一個元素的值
Ltrim修剪到指定范圍內的清單
Rpop從隊列的右邊出隊一個元素
Rpoplpush刪除列表中的最後一個元素,將其追加到另一個列表
Rpush從隊列的右邊入隊一個元素
Rpushx從隊列的右邊入隊一個元素,僅隊列存在時有效
Redis支持php、python、c等介面
應用場景:
Redislist的應用場景非常多,也是Redis最重要的數據結構之一,比如twitter的關注列表,粉絲列表等都可以用Redis的list結構來實現。
Lists就是鏈表,相信略有數據結構知識的人都應該能理解其結構。使用Lists結構,我們可以輕松地實現最新消息排行等功能。
Lists的另一個應用就是消息隊列,
可以利用Lists的PUSH操作,將任務存在Lists中,然後工作線程再用POP操作將任務取出進行執行。Redis還提供了操作Lists中某一段的api,你可以直接查詢,刪除Lists中某一段的元素。
如果需要還可以用redis的Sorted-Sets數據結構來做優先隊列.可以給每條消息加上一個唯一的序號。這里就不詳細介紹了。
實現方式:
Redislist的實現為一個雙向鏈表,即可以支持反向查找和遍歷,更方便操作,不過帶來了部分額外的內存開銷,Redis內部的很多實現,包括發送緩沖隊列等也都是用的這個數據結構。
示意圖:
1)入隊