• 
    

    
    

      99热精品在线国产_美女午夜性视频免费_国产精品国产高清国产av_av欧美777_自拍偷自拍亚洲精品老妇_亚洲熟女精品中文字幕_www日本黄色视频网_国产精品野战在线观看 ?

      基于Redis的微博系統(tǒng)基本功能設(shè)計

      2016-11-16 13:19:36李磊
      電腦知識與技術(shù) 2016年25期
      關(guān)鍵詞:微博

      李磊

      摘要:微博系統(tǒng)對信息實時性和并發(fā)性的要求,傳統(tǒng)的關(guān)系型數(shù)據(jù)庫無法滿足性能要求。Key-Value模型的內(nèi)存數(shù)據(jù)庫Redis,非常適合微博系統(tǒng)對數(shù)據(jù)快速存取的需要。

      關(guān)鍵詞:Redis;Key-Value;微博

      中圖分類號:TP311 文獻(xiàn)標(biāo)識碼:A 文章編號:1009-3044(2016)25-0061-03

      Abstract:Microblog system requirements for information-real-time performance and concurrency. Traditional relational database does not meet performance requirements. Key-Value model memory database Redis, very suitable for the microblog system with fast access to the data needed.

      Key words:Redis; Key-Value; Microblog

      1 概述

      微博系統(tǒng)類似于一個群聊的龐大聊天室,每時每刻都會有大量的消息產(chǎn)生,而且產(chǎn)生的消息會反饋給需要的用戶,這樣就要求數(shù)據(jù)的讀寫非???。關(guān)系型數(shù)據(jù)庫在數(shù)據(jù)量超過一定規(guī)模時,由于自身邏輯相對復(fù)雜,在信息檢索上無法滿足用戶的體驗。

      Redis數(shù)據(jù)庫本身的數(shù)據(jù)就放在內(nèi)存中,而且有合適的數(shù)據(jù)結(jié)構(gòu)。Twitter、新浪微博都是目前最大的Redis用戶。

      2 Redis介紹

      Redis是一個速度非??斓姆顷P(guān)系型數(shù)據(jù)庫。Redis可以存儲鍵(Key)與5種不同類型的值(Value)之間的映射,可以將存儲在內(nèi)存中的鍵值對持久化到硬盤。Redis還可以使用復(fù)制特性來擴(kuò)展讀性能,使用客戶端分片來擴(kuò)展寫性能。

      其重要特性如下:

      ① 持久化:Redis定期把數(shù)據(jù)異步flush到硬盤進(jìn)行保存。服務(wù)器重啟,數(shù)據(jù)不會丟失。

      ② 主從復(fù)制:主要用1臺服務(wù)器進(jìn)行數(shù)據(jù)備份與恢復(fù)。

      ③ Vitual Memory功能:物理內(nèi)存畢竟是有限的,這技術(shù)主要是把很少用的Value保存到硬盤,而Key保留在內(nèi)存做檢索,提高訪問性能。

      ④ 多種數(shù)據(jù)結(jié)構(gòu)支持:Redis的Key是string類型,Value的類型有:string、set、list、zset(sorted set)、hash。針對每種數(shù)據(jù)類型,還提供相應(yīng)的操作命令,比如list類型有LPOP、LPUSH、RPOP、RPUSH等操作,set類型SDIFF(差運算)、SINTER(交運算)、SUNION(并運算)等操作①。

      3 PHP和Redis構(gòu)建微博系統(tǒng)基本功能

      利用PHP的Redis擴(kuò)展,在PHP中實現(xiàn)微博系統(tǒng)新用戶的創(chuàng)建、消息發(fā)布、關(guān)注與粉絲設(shè)計、消息推送等基本功能。PHP版本為5.5.12,Redis版本為3.0.501。

      3.1 用戶信息表示

      Redis hash是一個string類型的field和value的映射表.一個key可對應(yīng)多個field,一個field對應(yīng)一個value。將一個對象存儲為hash類型,較于每個字段都存儲成string類型更能節(jié)省內(nèi)存。新建一個hash對象時開始是用zipmap(又稱為small hash)來存儲的。這個zipmap其實并不是hash table,但是zipmap相比正常的hash實現(xiàn)可以節(jié)省不少hash本身需要的一些元數(shù)據(jù)存儲開銷。盡管zipmap的添加,刪除,查找都是O(n),但是由于一般對象的field數(shù)量都不太多。所以使用zipmap也是很快的,也就是說添加刪除平均還是O(1)。如果field或者value的大小超出一定限制后,Redis會在內(nèi)部自動將zipmap替換成正常的hash實現(xiàn).。

      這里我們在數(shù)據(jù)庫中表示用戶信息和發(fā)布的消息都用Redis的hash結(jié)構(gòu)。用戶信息如表1。

      創(chuàng)建新用戶時,我們用到一個user:id:的計數(shù)器,實際就是Redis的一個Key,初始一個值,然后每次添加到user:uid的hash后值要自增1。用用戶信息中l(wèi)ogin和id兩個filed的值構(gòu)造另一個hash表users:,用來建立login和id之間的映射。關(guān)鍵代碼如下:

      if($redis->hget("users:",$login)){echo "{$login}已經(jīng)存在,重新輸入";}

      else{$uidarray=$redis->multi()->incr("user:id:")->exec();

      $uid=$uidarray[0];

      $userinfo=array(

      "login"=>$login,

      "id"=>$uid,

      "name"=>$name,

      "following"=>0,

      "fans"=>0,

      "posts"=>0,

      "signup"=>time());

      $redis->multi()->hset("users:",$login,$uid)

      ->hmset("user:{$uid}",$userinfo)->exec();}

      3.2 發(fā)布的消息表示

      用戶發(fā)布的消息也用hash表示,結(jié)構(gòu)如表2。

      發(fā)布消息時候,也用到一個計數(shù)器message:mid:,其值傳給消息中的mid,然后自增1,保證每個消息都有不同的mid。發(fā)布消息時,不僅要添加message:mid一個新的值,還要修改user:uid中的posts域的值。關(guān)鍵代碼如下:

      $midarray=$redis->multi()->incr("message:mid:")->exec();

      $mid=$midarray[0];

      $messageinfo=array(

      "content"=>$content,

      "time"=>time(),

      "mid"=>$mid,

      "uid"=>$uid,

      "login"=>$login);

      $redis->multi()->hmset("message:{$mid}",$messageinfo)

      ->hincrby("user:{$uid}","posts",1)->exec();

      3.3 用戶主頁時間線和個人時間線

      Redis提供zset這種有序集合數(shù)據(jù)結(jié)構(gòu)。通過zadd命令添加的成員,按照score的值排序,默認(rèn)score的值遞增。在微博系統(tǒng)中利用該數(shù)據(jù)結(jié)構(gòu)的特點,可以很方便的取出最新的消息。

      用戶主頁時間是指,當(dāng)用戶登錄后,能看到用戶以及用戶關(guān)注的人所發(fā)布的消息列表,這個列表以發(fā)布消息的時間排序。在Redis中用戶主頁時間線結(jié)構(gòu)如表3。

      用戶個人時間線僅僅只有用戶個人發(fā)布的消息列表,也是以發(fā)布時間排序。用戶個人時間線profile:uid結(jié)構(gòu)如下表4。

      3.4 關(guān)注者列表和粉絲列表

      微博系統(tǒng)就是要讓用戶之間分享各自的構(gòu)想、想法。當(dāng)A用戶開始關(guān)注或取消關(guān)注B用戶的時候,我們不僅要更新A用戶的關(guān)注列表following:A和A用戶的個人信息中關(guān)注數(shù)量following的值,還要更新B用戶的粉絲列表fans:B和B用戶的個人信息中粉絲數(shù)量fans的值。最后把B用戶發(fā)布的消息,profile:B中的消息,更新到A用戶的主頁時間線home:A。兩個列表都用Redis的zset有序集合結(jié)構(gòu)表示。表5為關(guān)注者列表結(jié)構(gòu),表6位粉絲列表結(jié)構(gòu)。

      開始關(guān)注操作關(guān)鍵代碼如下:

      define("HOME_TIMELINE_SIZE",1000);

      $fkey1="following:{$uid}";

      $fkey2="fans:{$other_id}";

      $have=$redis->zscore($fkey1,$other_id);

      if($have==true){ echo "{$uid}已經(jīng)關(guān)注{$other_id}";}

      else{$time=time();

      $values=$redis->multi()->zadd($fkey1,$other_id,$time)

      ->zadd($fkey2,$uid,$time)

      ->zrevrange("profile:{$other_id}",0,HOME_TIMELINE_SIZE-1,true)

      ->exec();

      $redis->multi()->hincrby("user:{$uid}","following",$values[0])

      ->hincrby("user:{$other_id}","fans",$values[1])->exec();

      if($values[2]){//獲取$other_id發(fā)布的消息不為空

      foreach($values[2] as $key=>$value)

      { $redis->multi()->zadd("home:{$uid}",$value,$key)->exec();}}}

      取消操作關(guān)鍵代碼如下:

      define("HOME_TIMELINE_SIZE",1000);

      $fkey1="following:{$uid}";

      $fkey2="fans:{$other_id}";

      $have=$redis->zrangebyscore($fkey1,$other_id,$other_id,array(true,1));

      if($have==false){echo "{$uid}沒有關(guān)注{$other_id}";}

      else{$values=$redis->multi()->zrem($fkey1,$other_id)

      ->zrem($fkey2,$uid)

      ->zrevrange("profile:{$other_id}",0,HOME_TIMELINE_SIZE-1,true)

      ->exec();

      $redis->multi()->hincrby("user:{$uid}","following",-$values[0])

      ->hincrby("user:{$other_id}","fans",-$values[1])->exec();

      if($values[2]){//獲取$other_id發(fā)布的消息不為空

      foreach($values[2] as $key=>$value)

      {$redis->multi()->zrem("home:{$uid}",$key)->exec();}}}

      3.5 消息推送

      在3.2節(jié)里面說明的是消息發(fā)布后,除了進(jìn)行消息信息添加以外,用戶個人信息中發(fā)布消息數(shù)量posts值得自增。我們還應(yīng)該接著把發(fā)布的消息告訴給個人時間線和主頁時間線,也就是在profile:uid(uid為發(fā)布消息的用戶id)中添加消息編號mid和時間戳time,并且在home:uid(uid為發(fā)布消息的用戶id)中也添加消息編號和時間戳time,這個時間戳應(yīng)該是消息發(fā)布的時候服務(wù)器的時間戳。然后還要在粉絲的主頁時間線home:uid(發(fā)布消息用戶的粉絲id)中添加同樣的數(shù)據(jù)。由于微博系統(tǒng)中有的用戶粉絲數(shù)量非常大,如果同步更新可能會導(dǎo)致用戶長時間等待。所以,在更新的時候,可以先更新fans:uid(uid為發(fā)布消息的用戶id)集合中前面1000個關(guān)注者,對每個關(guān)注者的home:uid進(jìn)行更新。關(guān)鍵代碼如下:

      $redis->multi()->zadd("profile:{$uid}",$time,$mid)

      ->zadd("home:{$uid}",$time,$mid)->exec();

      $fans=$redis->zrevrange("fans:{$uid}",0,1000,true);

      foreach($fans as $key=>$value)

      { $redis->zadd("home:{$value}",$time,$mid);}

      如果存在超過1000個用戶的情況,可以設(shè)計一個延遲功能來進(jìn)行轉(zhuǎn)發(fā),避免發(fā)布消息的用戶長時間等待。

      4 總結(jié)和展望

      Redis本身提供了很多的數(shù)據(jù)結(jié)構(gòu),靈活應(yīng)用可以構(gòu)造適合微博系統(tǒng)的數(shù)據(jù)庫。這里我們搭建了php+redis環(huán)境,做一個簡單的微博系統(tǒng),實現(xiàn)基本功能。要開發(fā)像Twitter、sina微博等系統(tǒng),還要考慮更復(fù)雜的數(shù)據(jù)構(gòu)造實現(xiàn)更多的功能,以及如何擴(kuò)展服務(wù)器來提高服務(wù)質(zhì)量。

      參考文獻(xiàn):

      [1] 唐誠.Redis數(shù)據(jù)庫在微博系統(tǒng)中的實踐[J].廈門城市學(xué)院學(xué)報,2012,14(3):55-59.

      [2] Josianh L Carlson.Redis實戰(zhàn)[M].北京:人民郵電出版社,2015.

      [3] 王艷,董麗麗.NoSql與關(guān)系數(shù)據(jù)庫相結(jié)合的設(shè)計與實踐[J].電腦知識與技術(shù), 2014(9).

      猜你喜歡
      微博
      青少年數(shù)字素養(yǎng)的社會與文化內(nèi)涵及其教育啟示
      微博信息傳播存在的主要問題和對策研究
      官方微博輿論引導(dǎo)方式探究
      今傳媒(2016年10期)2016-11-22 12:24:01
      “985工程”高校圖書館閱讀推廣的調(diào)查與分析
      中國市場(2016年38期)2016-11-15 23:47:47
      微信與微博平臺謠言差異分析
      大學(xué)出版社微博傳播分析及發(fā)展策略
      打造醫(yī)院里的“主流媒體”
      事實與流言的博弈
      人間(2016年26期)2016-11-03 18:19:04
      基于微博營銷的企業(yè)推廣模式研究
      重大突發(fā)事件中微博之力不微
      人民論壇(2016年27期)2016-10-14 13:08:58
      新密市| 岳普湖县| 南乐县| 凤山县| 武陟县| 盈江县| 永福县| 文水县| 怀化市| 台安县| 浦北县| 甘德县| 平顺县| 新巴尔虎右旗| 丹东市| 华坪县| 手游| 麟游县| 江城| 蓝田县| 岑溪市| 吕梁市| 迁安市| 华宁县| 柘城县| 兴化市| 渭南市| 陆丰市| 永春县| 科尔| 东方市| 东平县| 石柱| 平远县| 古浪县| 龙泉市| 方城县| 宁武县| 唐河县| 陆良县| 图片|