国产日韩欧美一区二区三区三州_亚洲少妇熟女av_久久久久亚洲av国产精品_波多野结衣网站一区二区_亚洲欧美色片在线91_国产亚洲精品精品国产优播av_日本一区二区三区波多野结衣 _久久国产av不卡

?

Redis在即時通訊系統(tǒng)中的應用

2017-02-27 03:11:24李鵬鵬鄭揚飛劉玉龍
軟件 2017年1期
關鍵詞:即時通訊服務端內(nèi)存

李鵬鵬,鄭揚飛,劉玉龍

(華北計算技術研究所,北京 100083)

Redis在即時通訊系統(tǒng)中的應用

李鵬鵬,鄭揚飛,劉玉龍

(華北計算技術研究所,北京 100083)

傳統(tǒng)的即時通訊系統(tǒng)的弊端之一是數(shù)據(jù)庫I/O次數(shù)頻繁,因為在IM中大量短而多的消息持續(xù)在磁盤的數(shù)據(jù)庫上進行讀寫。為了解決數(shù)據(jù)庫造成的系統(tǒng)瓶頸,選取Mysql和內(nèi)存Key-Value引擎的NoSQL數(shù)據(jù)庫Redis兩級存儲,從而給出基于XMPP的即時通訊系統(tǒng)高可用的優(yōu)化方案。

Redis;XMPP;即時通訊系統(tǒng);數(shù)據(jù)分片

0 引言

即時通信[1]是以Internet網(wǎng)絡及有線、無線網(wǎng)絡為基礎物理設施,在交互雙方之間實時地傳送文本、語音和圖像等信息的通信方式。新時代的即時通訊系統(tǒng),用戶需要其提供更快、更穩(wěn)定、更可靠的即時通信服務。伴隨著Internet技術的不斷發(fā)展,影響網(wǎng)絡速度的瓶頸主要集中在訪問距離和服務器承載負荷能力方面[2]。內(nèi)存數(shù)據(jù)庫以其明顯的優(yōu)勢補足了傳統(tǒng)通信技術架構[3]的不足。本文主要介紹NoSQL在即時通訊系統(tǒng)中的設計與實踐。

1 Redis技術研究

1.1 Redis技術簡介

Redis[4]是一個開源的使用ANSI C語言編寫、支持網(wǎng)絡、可基于內(nèi)存亦可持久化的日志型、Key-Value數(shù)據(jù)庫,并提供多種語言的API。

Redis是一個Key-Value存儲系統(tǒng)。和Memcached類似,它支持存儲的value類型相對更多,包括string(字符串)、list(鏈表)、set(集合)和zset(有序集合)。這些數(shù)據(jù)類型都支持push/pop、add/remove及取交集并集和差集及更豐富的操作,而且這些操作都是原子性的。在此基礎上,Redis支持各種不同方式的排序。與memcached一樣,為了保證效率,數(shù)據(jù)都是緩存在內(nèi)存中。區(qū)別的是Redis會周期性的把更新的數(shù)據(jù)寫入磁盤或者把修改操作寫入追加的記錄文件,并且在此基礎上實現(xiàn)了master-slave(主從)同步。

Redis是一個遠程內(nèi)存數(shù)據(jù)庫[5],它不僅性能強勁,而且還具有復制特性以及為解決問題而生的獨一無二的數(shù)據(jù)模型。Redis提供了5種不同類型的數(shù)據(jù)結構,各式各樣的問題都可以很自然地映射到這些數(shù)據(jù)結構上:Redis的數(shù)據(jù)結構致力于幫助用戶解決問題,而不會像其他數(shù)據(jù)庫那樣,要求用戶扭曲問題來適應數(shù)據(jù)庫。除此之外,通過復制、持久化(persistence)和客戶端分片(client-side sharding)等特性,用戶可以很方便地將Redis擴展成一個能夠包含數(shù)百GB數(shù)據(jù)、每秒處理上百萬次請求的系統(tǒng)。

1.2 Redis特性

NoSQL概念在2009年被提了出來。NoSQL最常見的解釋是“non-relational”,“Not Only SQL”也被很多人接受。(“NoSQL”一詞最早于1998年被用于一個輕量級的關系數(shù)據(jù)庫的名字。)

傳統(tǒng)的關系數(shù)據(jù)庫具有不錯的性能,高穩(wěn)定型,久經(jīng)歷史考驗,而且使用簡單,功能強大,同時也積累了大量的成功案例。在互聯(lián)網(wǎng)領域,MySQL成為了絕對靠前的王者,毫不夸張的說,MySQL為互聯(lián)網(wǎng)的發(fā)展做出了卓越的貢獻。隨著時間的推移,線上數(shù)據(jù)越來越多,悄然進入大數(shù)據(jù)時代。網(wǎng)站開始快速發(fā)展,火爆的論壇、博客、sns、微博逐漸引領web領域的潮流。巨大的流量給公司帶來了可觀的收入,也帶來了數(shù)據(jù)庫存儲與查詢并優(yōu)的瓶頸。

Redis是基于C/C++開發(fā)的一款K-V數(shù)據(jù)庫,特點是運行異常快,使用協(xié)議是類Telnet。除此之外還有以下幾個特性:

● Redis持久化

通常,Redis將數(shù)據(jù)存儲于內(nèi)存中,或被配置為使用虛擬內(nèi)存。通過兩種方式可以實現(xiàn)數(shù)據(jù)持久化:使用截圖的方式,將內(nèi)存中的數(shù)據(jù)不斷寫入磁盤;或使用類似MySQL的日志方式,記錄每次更新的日志。前者性能較高,但是可能會引起一定程度的數(shù)據(jù)丟失;后者相反。

● Redis主從同步

Redis支持將數(shù)據(jù)同步到多臺從庫,這種特性對提高讀取性能非常有益。

● Redis數(shù)據(jù)類型

作為Key-value型數(shù)據(jù)庫,Redis也提供了鍵(Key)和鍵值(Value)的映射關系。但是,除了常規(guī)的數(shù)值或字符串,Redis的鍵值還可以是以下形式之一:

? Lists(列表)

? Sets(集合)

? Sorted sets(有序集合)

? Hashes(哈希表)

鍵值的數(shù)據(jù)類型決定了該鍵值支持的操作。Redis支持諸如列表、集合或有序集合的交集、并集、查集等高級原子操作;同時,如果鍵值的類型是普通數(shù)字,Redis則提供自增等原子操作。

● 支持事務

Redis事務可以一次執(zhí)行多個命令,并且?guī)в幸韵聝蓚€重要的保證。第一,事務是一個單獨的隔離操作,事務中的所有命令都會序列化、按順序地執(zhí)行。事務在執(zhí)行的過程中,不會被其他客戶端發(fā)送來的命令請求所打斷;第二,事務是一個原子操作,事務中的命令要么全部被執(zhí)行,要么全部都不執(zhí)行。

一個事務從開始到執(zhí)行會經(jīng)歷以下三個階段:開始事務,命令入隊,執(zhí)行事務。

● Redis管道技術

Redis是一種基于客戶端-服務端模型以及請求/響應協(xié)議的TCP服務。這意味著通常情況下一個請求會遵循以下步驟:首先,客戶端向服務端發(fā)送一個查詢請求,并監(jiān)聽Socket返回,通常是以阻塞模式,等待服務端響應;然后,服務端處理命令;最后,將結果返回給客戶端。Redis管道技術可以在服務端未響應時,客戶端可以繼續(xù)向服務端發(fā)送請求,并最終一次性讀取所有服務端的響應。

Redis其實開創(chuàng)了一種新的數(shù)據(jù)存儲思路,使用Redis,我們不用再面對功能單調的數(shù)據(jù)庫時,把精力放在如何把大象放進冰箱的問題,而是利用Redis提供的靈活多變的數(shù)據(jù)結構和數(shù)據(jù)操作,為不同的大象構建不同的冰箱。根據(jù)Redis的特性,總結出其最佳應用場景有:適用于數(shù)據(jù)變化快且數(shù)據(jù)庫大小可遇見(適合內(nèi)存容量)的應用程序,例如:股票價格、數(shù)據(jù)分析、實時數(shù)據(jù)搜集、實時通訊。

1.3 Redis優(yōu)勢分析

Redis有著更為復雜的數(shù)據(jù)結構并且提供對他們的原子性操作,這是一個不同于其他數(shù)據(jù)庫的進化路徑。Redis的數(shù)據(jù)類型都是基于基本數(shù)據(jù)結構的同時對程序員透明,無需進行額外的抽象。Redis運行在內(nèi)存中但是可以持久化到磁盤,所以在對不同數(shù)據(jù)集進行高速讀寫時需要權衡內(nèi)存,因為數(shù)據(jù)量不能大于硬件內(nèi)存。在內(nèi)存數(shù)據(jù)庫方面的另一個優(yōu)點是,相比在磁盤上相同的復雜的數(shù)據(jù)結構,在內(nèi)存中操作起來非常簡單,這樣Redis可以做很多內(nèi)部復雜性很強的事情。同時,在磁盤格式方面他們是緊湊的以追加的方式產(chǎn)生的,因為他們并不需要進行隨機訪問。

Redis特點突出,正是因為這些特點所以才凸顯其以下幾個優(yōu)點:

? 性能極高-Redis能讀的速度是110000次/s,寫的速度是81000次/s。

? 豐富的數(shù)據(jù)類型-Redis支持二進制案例的Strings,Lists,Hashes,Sets及Ordered Sets數(shù)據(jù)類型操作。

? 原子-Redis的所有操作都是原子性的,同時Redis還支持對幾個操作全并后的原子性執(zhí)行。

? 豐富的特性-Redis還支持publish/subscribe,通知,key過期等等特性。

2 Redis存儲設計

即時通訊系統(tǒng)一般分為客戶端與服務端,客戶端較輕,關鍵邏輯在服務端,一般分為三到四層,采用B/S和C/S混合架構。即時通訊系統(tǒng),主要包含的業(yè)務場景有,注冊登錄、即時會話[6]、組織機構、文件傳輸。對于所有的用戶,有在線和離線的狀態(tài)。并且,對于在線狀態(tài)用戶的長連接需要有專用服務器來維護,表現(xiàn)在架構中的連接服務。系統(tǒng)邏輯架構示意圖如圖1。

2.1 數(shù)據(jù)庫詳細設計

數(shù)據(jù)庫設計圖,見圖2:

如圖2所示,根據(jù)業(yè)務邏輯層,將數(shù)據(jù)庫進行分庫設計[7],并且每一個分片是主從設計。

初始設計使用4臺MySQL分庫。分庫的策略是:

圖1 系統(tǒng)邏輯架構示意圖

圖2 數(shù)據(jù)庫設計圖

如公式(1),proxyNo代表選擇Redis數(shù)據(jù)庫編號0-3。具體計算公式解釋為,使用SID(發(fā)送方用戶ID)+RID(接收方用戶ID) mod 64,0-15落在第0個庫rdb0上,16-31落在第1個庫rdb1上,32-47落在第2個庫rdb2上,48-63落在第3個庫rdb3上。這樣的優(yōu)勢在于,A用戶發(fā)送B用戶和B用戶發(fā)送A用戶的消息,都會落在同一個底層數(shù)據(jù)庫?;诖嗽O計,對于查詢用戶A和B的聊天記錄,只需要使用一個SQL查詢即可,而不需要寫腳本跨庫查詢,減少IO的開銷,以達到性能提升的效果。

分庫設計和主從備份實現(xiàn)了高并發(fā)和高可用的設計。但是,當Mysql單表的數(shù)據(jù)量達到1000W的時候,使用索引等對表進行優(yōu)化已經(jīng)到達瓶頸,所以需要從DDL、DML、DQL對數(shù)據(jù)庫進行設計。根據(jù)業(yè)務需求,在Redis上設計了消息表、用戶狀態(tài)表及其索引,并且實現(xiàn)兩個用戶之間消息記錄的查詢。

(a)針對聊天消息表

按照時間進行分區(qū)。基于此設計的原因在于:用戶使用場景一般為按照時間逆序查詢聊天記錄,越新的數(shù)據(jù)越熱。創(chuàng)建聊天表的SQL如圖3。

圖3 消息表創(chuàng)建sql

(b)用戶狀態(tài)表

該表主要用于維護用戶連接信息,當長鏈接被意外打斷,用此表信息恢復用戶之前狀態(tài),起到“保留現(xiàn)場”的作用。創(chuàng)建表sql如圖4。

圖4 用戶狀態(tài)表創(chuàng)建sql

其中,sessionId是聊天雙方,(較小的ID在前,較大的ID在后)的會話狀態(tài)信息,pcMid是用戶pc端已讀的最大消息ID;mobileMid是用戶手機端已讀的最大消息ID;hashvalue是(發(fā)送方用戶ID+接收方用戶ID)mod 64計算后的值,為了記錄該條數(shù)據(jù)在具體的某一個數(shù)據(jù)庫中。

(c)未讀消息索引

對于未讀消息的查詢,為了實現(xiàn)大數(shù)據(jù)量更加高效的查詢,在數(shù)據(jù)庫中為消息表和用戶狀態(tài)表添加索引。創(chuàng)建索引SQL如圖5。

圖5 獲取未讀消息索引

(d)DQL未讀消息查詢

根據(jù)以上設計,查詢用戶id為1,2之間的聊天內(nèi)容,優(yōu)化[8]后的SQL語句如圖6。

2.2 業(yè)務場景應用

在3.1章節(jié)中介紹了數(shù)據(jù)庫的設計,并且給出了優(yōu)化設計方案。針對設計的方案,我們利用具體的業(yè)務場景來完成對設計方案的試驗。首先,圖7給出的是id為1的用戶與id為2的用戶之間的文本通訊過程以及步驟。

圖6 未讀消息SQL

圖7 業(yè)務結構圖

如圖7所示,首先,定義:發(fā)送方用戶ID為srcid,接收方用戶ID為destid,每個會話的當前消息ID為msgid(針對每個發(fā)送方和接收方,自增)。

針對離線消息的場景流程如下:

1. 發(fā)送方用戶通過電腦將消息發(fā)送至Web服務器.消息主要內(nèi)容(srcid,destid,msgid)

2. Web服務器根據(jù)srcid,destid獲取會話的mid(會話狀態(tài)的自增ID)

每個會話都按照較小ID在前,較大ID在后作為Redis的key,并且,每個會話的狀態(tài)信息都設置過期時間。如果Redis里沒有會話的狀態(tài),則用時間戳填充。數(shù)據(jù)格式如表1。

3. 將消息放入持久化隊列,并且更新Redis未讀消息列表

首先將(srcid,destid,mid,msg)放入持久化隊列,然后更新Redis的用戶未讀消息列表,未讀消息列表在Redis的存儲結構如表2。

表1 公共數(shù)據(jù)區(qū)數(shù)據(jù)結構

表2 PC端未讀消息存儲結構

如表2所示,Mobile端未讀消息存儲結構和PC端設計原理一致。其中,在接收方ID的前面增加一個前綴,表明是手機未讀消息還是PC未讀消息。這個作為表結構的key。而value是一個HashMap,這個HashMap的key是發(fā)送方ID,value是未讀消息數(shù)量。

一旦用戶登錄,直接拉取該用戶的HashMap內(nèi)容展示,這部分內(nèi)容是有過期時間的,假如用戶長時間未使用,這個PC-destid和Mobile-destid的條目將被刪除。如果程序發(fā)現(xiàn)這個條目不存在.則去數(shù)據(jù)庫中查詢未讀消息列表。

假如A的ID是1000,B的ID是1001,B給A發(fā)送了三條消息,但是A一直沒有在線。程序將做如下操作:

如果此時A登錄手機客戶端,點擊未讀消息.則對Redis操作如下,刪除對應條目。

在此情況下,并且回寫數(shù)據(jù)庫一個狀態(tài)標識(已讀的最大mid)。這個回寫數(shù)據(jù)庫的過程,也是異步的,每隔30 s回寫一次數(shù)據(jù)庫狀態(tài)。這樣的設計,雖然在數(shù)據(jù)庫上對不同類型設備進行了狀態(tài)冗余,但是保證了未讀消息在不同端多次提醒。

4. 如果發(fā)送方的其他設備在線,或者接收方的設備在線,則轉發(fā)消息。

5. JAVA從隊列中異步獲取消息,然后批量Insert到數(shù)據(jù)庫。

2.3 實驗驗證

對于系統(tǒng)設計的方案,編寫腳本進行性能測試[9]。測試結果,如。

圖8 測試結果圖

Redis插入效率,在不使用持久化的情況下,可以達到7.3 W;在持久化情況下,保證數(shù)據(jù)最終一致性的前提下,也可以達到2.3 W。針對本文的設計,此套系統(tǒng)可以勝任日均超1 KW量的即時通訊任務。

3 結論

在即時通訊系統(tǒng)中使用Redis進行優(yōu)化,為傳統(tǒng)IM的升級革新提供了新的思路。由于使用了無事務的NoSQL數(shù)據(jù)庫Redis,所以在本文中對所有消息有編號進行確認,類似于網(wǎng)絡中的ACK,解決了在故障情況下批量消息未成功發(fā)送到指定用戶端所帶來的數(shù)據(jù)丟失的問題。最后,基于Redis的即時通訊系統(tǒng),相比于傳統(tǒng)的即時通訊系統(tǒng)無論在性能還是用戶體驗度都有很大的提升,達到了預期的效果。

[1] 郭鑫杰. 即時通訊系統(tǒng)的設計與實現(xiàn)[D]. 南京大學2012.

[2] 林源晟. 基于XMPP協(xié)議的即時通信服務器的設計與實現(xiàn)[D]. 電子科技大學 2013.

[3] 董恒競. 一種企業(yè)移動應用平臺架構設計[J]. 軟件, 2016, 37(01)∶ 136-138.

[4] 馬豫星. Redis數(shù)據(jù)庫特性分析[J]. 物聯(lián)網(wǎng)技術. 2015(03).

[5] 邱祝文. 基于redis的分布式緩存系統(tǒng)架構研究[J]. 網(wǎng)絡安全技術與應用. 2014(10).

[6] 張勇, 裴東良, 張會兵. 消息傳輸系統(tǒng)研究[J]. 軟件, 2016, 37(3)∶ 51-54.

[7] 朱思征, 王山山, 敖麗娜, 等. 大數(shù)據(jù)環(huán)境下刀具倉儲與采購智能協(xié)同研究[J]. 軟件, 2016, 37(02)∶ 29-32.

[8] 楊淙鈞, 艾中良, 劉忠麟, 等. 基于多級列式索引的海量數(shù)據(jù)高效查詢設計[J]. 軟件, 2016, 37(3)∶ 79-83.

[9] 凌高源, 朱琳. 上網(wǎng)流量監(jiān)測管理軟件設計與實現(xiàn)[J]. 軟件, 2016, 37(01)∶ 48-52文獻內(nèi)容.

[10] Wang S, Liu Z, Sun Q, Zou H, Yang F. Towards an accurate evaluation of quality of cloud service in service-oriented cloud computing. Journal of Intelligent Manufacturing, 2014, 25(2)∶ 283-291.

The Application of Instant Messaging System Based on Redis

LI Peng-peng, ZHENG Yang-fei, LIU Yu-long
(North China Institute of Computing Technology, Beijing 100083)

One of the drawbacks of the traditional instant messaging system is the frequent number of database I / O, because a large number of short messages in IM continue to read and write on the disk database. In order to solve the system bottleneck caused by the database, the NoSQL database Redis two-level storage of Mysql and Key-Value engine of memory is selected, and the optimization scheme of XMPP-based instant communication system is presented.

Redis; XMPP protocol; Instant Messaging system; Database sharding

TP311

A

10.3969/j.issn.1003-6970.2017.01.024

李鵬鵬(1991-),男,研究生,計算機應用技術;鄭揚飛(1976-),男,高級工程師,主要研究方向為企業(yè)信息化,分布式系統(tǒng);劉玉龍,男,高級工程師,信息系統(tǒng)頂層設計,信息集成

本文著錄格式:李鵬鵬,鄭揚飛,劉玉龍. Redis在即時通訊系統(tǒng)中的應用[J]. 軟件,2017,38(1):115-119

猜你喜歡
即時通訊服務端內(nèi)存
“春夏秋冬”的內(nèi)存
當代陜西(2019年13期)2019-08-20 03:54:22
云存儲中基于相似性的客戶-服務端雙端數(shù)據(jù)去重方法
新時期《移動Web服務端開發(fā)》課程教學改革的研究
消費導刊(2018年8期)2018-05-25 13:19:48
民事訴訟中即時通訊記錄的證據(jù)采用進路
在Windows Server 2008上創(chuàng)建應用
即時通訊軟件發(fā)展模型的實證研究
東方教育(2016年19期)2017-01-16 12:34:53
科學技術哲學視域下的即時通訊
科技傳播(2015年14期)2015-12-13 04:20:18
即時通訊軟件WhatsApp
CHIP新電腦(2015年10期)2015-10-15 18:03:55
基于內(nèi)存的地理信息訪問技術
“鴿子”玩升級 黑你沒商量
陆丰市| 井研县| 罗平县| 庆阳市| 库尔勒市| 论坛| 定安县| 诏安县| 克拉玛依市| 江津市| 加查县| 甘孜| 缙云县| 鄄城县| 安乡县| 巴南区| 定日县| 大宁县| 车险| 凯里市| 榆中县| 西城区| 博乐市| 板桥市| 盐边县| 虹口区| 囊谦县| 临邑县| 喀喇沁旗| 宜宾市| 武强县| 茌平县| 壤塘县| 奉贤区| 重庆市| 衡水市| 大庆市| 商河县| 淮滨县| 杭锦后旗| 清流县|