摘 要: Redis+MySQL+MongoDB技術(shù)架構(gòu)實現(xiàn)了本項目中大數(shù)據(jù)存儲和實時云計算的需求。使用MongoDB切片的水平動態(tài)添加,,可在不中斷平臺業(yè)務(wù)系統(tǒng)的同時保障擴容后的查詢速度和云計算效能,;依據(jù)切片鍵索引分片,位于各切片獨立進行計算,,使大數(shù)據(jù)下的實時分析成為現(xiàn)實,。對于高頻訪問的數(shù)據(jù)放在了Redis中,有效地降低磁盤I/O,,使業(yè)務(wù)系統(tǒng)響應(yīng)更為敏捷,,滿足了高并發(fā)下應(yīng)用服務(wù)的高呑吐要求。
關(guān)鍵詞: 移動位置服務(wù)SaaS,;Redis,;MongoDB
基于移動位置服務(wù)的應(yīng)用是根據(jù)用戶所在位置提供的一種增值業(yè)務(wù),,主要通過移動定位技術(shù)獲得其當前所在位置,在電子地圖和業(yè)務(wù)平臺的支持下,,提供位置相關(guān)的信息服務(wù),。通過互聯(lián)網(wǎng)提供軟件服務(wù)的SaaS(Software as a Service)模式具有企業(yè)初期零投入,不需服務(wù)器,、系統(tǒng)研發(fā)等軟硬件投入等獨特的優(yōu)點,,為廣大中小企業(yè)解決前期資金投入不足的情況下開展信息化建設(shè),引入管理信息系統(tǒng)提供了一個可行的模式,。
1 項目簡介
基于此需求背景提出開發(fā)一種面向中小企業(yè)移動位置服務(wù)的SaaS平臺,,幫助所有具有外勤、外巡,、外服的戶外工作業(yè)務(wù)的中小企業(yè)降低成本,,將定位技術(shù)與智能手機客戶端相結(jié)合,利用運營商的GSM/WCDMA等無線網(wǎng)絡(luò),,為企業(yè)提供在外工作人員的具體位置和行走軌跡,,同時實現(xiàn)考勤簽到、快速審批,、位置標注,、語音群聊、數(shù)據(jù)上報,、區(qū)域預警,,更好地進行地理化分析、業(yè)績審視,,快速響應(yīng)客戶需求和有效管理員工,,深度鞏固企業(yè)在市場中主體地位和增強企業(yè)核心競爭力。
2 業(yè)務(wù)數(shù)據(jù)分析
移動位置服務(wù)的SaaS平臺作為企業(yè)移動互聯(lián)網(wǎng)應(yīng)用,,應(yīng)用過程將積累大量數(shù)據(jù),。其中包括:靜態(tài)信息(手機號碼、注冊信息,、手機型號等),;位置信息(行動軌跡、速度,、停留時間,、地點屬性);與APP關(guān)聯(lián)的數(shù)據(jù)(訪問行為,、社交行為,、交易行為等);交互特點(報告頻率、數(shù)據(jù)類型與格式等),。其數(shù)據(jù)容量和特點較傳統(tǒng)業(yè)務(wù)有較大地變化,。
2.1 數(shù)據(jù)來源分析
數(shù)據(jù)來源包括終端采集的數(shù)據(jù)和SaaS平臺數(shù)據(jù),終端數(shù)據(jù)涵蓋了Android,、IOS智能終端和PC端,,智能終端是企業(yè)應(yīng)用的數(shù)據(jù)采集器,是企業(yè)人在業(yè)務(wù)活動中“人體器官”的延伸,。同時還有部分數(shù)據(jù)源于PC端,;另外系統(tǒng)運行過程中,會產(chǎn)生大量日志數(shù)據(jù),。
(1)終端采集的數(shù)據(jù)
?、佘壽E數(shù)據(jù):以包括公司id,、用戶id、經(jīng)緯度,、地址,、定位時間、定位類型等信息的一個數(shù)據(jù)樣本為例,,默認30 s采集一次,,假如企業(yè)員工默認工作時間8小時,每個員工每天條數(shù)為2 080條,,假定用戶數(shù)為10 000,,那么每天有2 080萬條;單條數(shù)據(jù)占用空間184 KB,,10 000用戶一天占用空間約為3 GB,。
②常規(guī)業(yè)務(wù)數(shù)據(jù):常規(guī)業(yè)務(wù)數(shù)據(jù)種類有考勤,、工作計劃,、工作日志、申請,、事件提醒,、通知公告、銷售上報等,;保守預計單條數(shù)據(jù)容量為512 KB,,按每個用戶每天產(chǎn)生15條相關(guān)業(yè)務(wù),其數(shù)據(jù)量為7 680 KB,,10 000用戶一天產(chǎn)生數(shù)據(jù)量約為73 MB,。
③即時聊天和工作微博數(shù)據(jù):即時聊天和工作微博數(shù)據(jù)為非結(jié)構(gòu)化數(shù)據(jù),包含如下種類:語音,、圖片,、文本、位置分享等,。保守預計單條圖片語音數(shù)據(jù)量為: 100 KB,,按每個用戶每天產(chǎn)生30條,其數(shù)據(jù)量為3 000 KB,,10 000用戶一天產(chǎn)生數(shù)據(jù)量約為28 GB,。
(2)平臺數(shù)據(jù)
作為服務(wù)眾多企業(yè)的云平臺,,還有如下種類數(shù)據(jù)需要產(chǎn)生和管理:企業(yè),、企業(yè)組織、企業(yè)用戶,、用戶通信錄,、用戶通信錄個性化備注、群組名片等,;平臺方面的數(shù)據(jù)暫且不作考量,,與普遍的企業(yè)應(yīng)用基本類似。
2.2 數(shù)據(jù)特點分析
?。?)移動化,。與PC應(yīng)用相比較,移動應(yīng)用數(shù)據(jù)采集的時空變化了,,智能終端不知疲倦,,可以自動采集上報如位置等信息;同時移動化使得采集數(shù)據(jù)的便捷性得到了極大提高,,用手機拍照立即便可上傳,,相比過去的照相機采集沒有空間限制也沒有鏈接PC上傳的限制。
?。?)非結(jié)構(gòu)化,。采集的圖片語音等媒體數(shù)據(jù)非結(jié)構(gòu)化,例如采集門店的貨品陳列的圖片數(shù)據(jù)等,,工作微博分享的數(shù)據(jù)文檔化,,與傳統(tǒng)結(jié)構(gòu)化、需要事務(wù)支持的數(shù)據(jù)有明顯差異,。
?。?)平臺級增量化。與以往企業(yè)級應(yīng)用對應(yīng)一家企業(yè)增量相比,,平臺級數(shù)據(jù)增量化帶來的數(shù)據(jù)量巨大增加,,通過上面的分析,,10 000用戶每天會帶來大約30 GB的數(shù)據(jù)增量。30 GB數(shù)據(jù)有些均勻地提交到平臺,,有些會以峰值的方式提交到平臺,;考勤通常集中在上下班時段,而軌跡則均勻分布在所有上班時間,。
針對以上數(shù)據(jù)分析,,如何解決其大容量和非結(jié)構(gòu)化數(shù)據(jù)特點面臨的存儲和處理的挑戰(zhàn)?通過技術(shù)選型和前期的測試數(shù)據(jù)對比,,選用了Redis+MySQL+Mongodb架構(gòu)的解決方案,。
3 相關(guān)技術(shù)
3.1 Redis簡介
Redis(Remote Dictionary Server)是一個使用ANSI C語言開發(fā)的開源的Key-Value存儲系統(tǒng),它和目前較流行的Memcached類似,,都是基于內(nèi)存(緩存)的數(shù)據(jù)存儲方式,,不同的是Redis支持的數(shù)據(jù)類型更加豐富并且對每種數(shù)據(jù)結(jié)構(gòu)提供了豐富的操作。同時,,Redis不同于Memcached之處在于它會將更新的數(shù)據(jù)異步的持久化到硬盤中或者把進行過的修改操作寫入日志文件中,。Redis雖然是Key/Value形式的數(shù)據(jù)庫,但是它吸收了部分關(guān)系型數(shù)據(jù)庫的優(yōu)點,,如在能保存Lists和Sets類型的數(shù)據(jù)的同時,還能完成排序等高級功能,,同時在實現(xiàn)INCR(自增),、SETNX(若不存在Key則創(chuàng)建并設(shè)值)等功能時保證其操作的原子性。在此基礎(chǔ)上還實現(xiàn)了Master-Slave(主從)同步[2],。Redis主從復制特點:(1)支持一個Master可以擁有多個Slave,,同時Slave還可以接收其他的Slave;(2)主從復制不會阻塞Master和Slave,,在同步數(shù)據(jù)時,,Master和Slave都可以接收Client請求[2]。
3.2 MongoDB及其自動分片簡介[3]
MongoDB是一個基于分布式文件存儲的數(shù)據(jù)庫[4],。由C++語言編寫,。它支持的數(shù)據(jù)結(jié)構(gòu)非常松散,是類似json的bson格式,,因此可以存儲比較復雜的數(shù)據(jù)類型,。MongoDB的特點是面向集合存儲,模式自由,,支持動態(tài)查詢,、完全索引、查詢,、復制和故障轉(zhuǎn)移,,自動處理碎片[5]。MongoDB的核心理念在于文檔模型,它是MongoDB數(shù)據(jù)的基本單元,,等價于關(guān)系型數(shù)據(jù)庫的行,。MongoDB中的集合等價于關(guān)系型數(shù)據(jù)庫中的表。一個單一的MongoDB可以承載多個獨立的數(shù)據(jù)庫,,每個數(shù)據(jù)庫可以擁有自己的集合和管理權(quán)限,。
MongoDB的分片架構(gòu)是指把數(shù)據(jù)分割成不同部分,在不同的機器上的存儲過程,,通過分割數(shù)據(jù)到不同的服務(wù)器上,,使得無需使用更強大的機器來存儲更多的數(shù)據(jù)和處理更大的負載。MongoDB支持自動分片,,集群可以自動分割數(shù)據(jù)和數(shù)據(jù)的再均衡,。MongoDB提供以下的分片技術(shù):(1)對負載的變換和數(shù)據(jù)的分布自動平衡;(2)動態(tài)添加額外服務(wù)器,;(3)無單點故障,;(4)自動故障轉(zhuǎn)移[6]。
4 技術(shù)實現(xiàn)
4.1 架構(gòu)功能角色
Redis+MySQL+Mongodb架構(gòu)對應(yīng)功能角色如下,。
Redis:基于內(nèi)存高速緩存,,保存集群中央會話,即時通信離線消息隊列,,即時通信重發(fā)消息集合,,用戶令牌生命周期管理,應(yīng)用高頻訪問數(shù)據(jù)緩存,,HTML5模板數(shù)據(jù)緩存,,靜態(tài)應(yīng)用資源緩存。
MySQL:進行事務(wù)數(shù)據(jù)存儲:相關(guān)企業(yè)帳號數(shù)據(jù),,企業(yè)常規(guī)業(yè)務(wù)數(shù)據(jù),,企業(yè)平臺交易數(shù)據(jù)。
Mongodb:進行非結(jié)構(gòu)化文檔數(shù)據(jù)存儲:包括圖片,、圖標,、語音、工作微博文本以及結(jié)合位置數(shù)據(jù)的非結(jié)構(gòu)化的文檔數(shù)據(jù),,需要動態(tài)擴展無固定模式的數(shù)據(jù),,應(yīng)用日志數(shù)據(jù),需要map-reduce計算的數(shù)據(jù),。
4.2 可靠性和可用性保障措施
為了保證生產(chǎn)系統(tǒng)數(shù)據(jù)可靠性和可用性,,規(guī)避Redis+MySQL+Mongodb單點故障,分別作了主從備份,,在此基礎(chǔ)上采用了KEEPALIVE,,通過VRRP協(xié)議實現(xiàn)了故障的自動切換,。Redis配置了主從,MySQL配置了主從,,Mongodb配置了切片,;詳細配置清單舉例如下。
Redis主從配置需要在從配置文件Redis.conf指定主IP和端口:slaveof 192.168.10.10 6379
MySQL主從配置:
主配置:server-id=1,;log-bin=mysql-bin,;binlog-do-db=wqt_web
從配置:server-id=2;log-bin=msyql-bin,;master-host=192.168.10.3,;master-user=slaveuser;master-password=gotop4001680756,;master-port=3306,;…
Mongodb切片配置:
mongod-shardsvr-port 10001-dbpath=/home/data/shard11/-logpath /home/data/shard11/mongodb.log--fork
mongod-shardsvr-port 10002-dbpath=/home/data/shard12/-logpath
…
mongo 127.0.0.1:20000/admin
配置分片必須要鏈接admin集合。鏈接成功后可以把分片加入集群:
db.runCommand({"addshard":"127.0.0.1:10001"})
…
db.runCommand({"addshard":"127.0.0.1:10004"})
這樣就成功地把4個shard加入了分片,。制定分片的規(guī)則如下:
db.runCommand({"shardcollection":"kingfihser.tablename",,"key":{"primaryKey":1}})
激活分片的設(shè)置:db.runCommand({"enablesharding":"kingfisher"}),最后成功的配置了分片,。
4.3 詳細代碼
4.3.1 Redis實現(xiàn)案例
在通信中,,作為發(fā)布訂閱隊列使用,Web發(fā)布消息,,進入Redis發(fā)布訂閱頻道,,通信中心消費此頻道消息,所有的信息發(fā)布都在Redis中進行,,從而提高了響應(yīng)的速度。
public boolean sendMsg(String msg){
boolean rebool=true,;
Jedis jedis=null,;
try{
jedis=(Jedis)pool.getResource();
jedis.publish("kingfisher.*",,msg),;
}catch(Exception e){
e.printStackTrace();
rebool=false,;
}finally{
pool.returnResource(jedis),;
}
return rebool;
}
4.3.2 Mysql實現(xiàn)
進行事務(wù)數(shù)據(jù)存儲:包括相關(guān)企業(yè)帳號數(shù)據(jù),,企業(yè)常規(guī)業(yè)務(wù)數(shù)據(jù),,企業(yè)與平臺交易數(shù)據(jù)。此部分的存儲計算采用HIBERNATE+SPRING方式實現(xiàn),。
4.3.3 Mongodb實現(xiàn)案例
?。?)媒體數(shù)據(jù)利用GFS網(wǎng)格文件子系統(tǒng)存儲,。
class fileservice(BaseHandler):
def get(self):
id=self.get_argument("id","")
f=GridOut(self.mongo.fs,,ObjectId(id))
try:
fn=f.filename.lower()
…
self.write(f.read())
def post(self):
…
def delete(self):
…
?。?)工作微博內(nèi)容和二維空間索引,以及軌跡數(shù)據(jù)的索引和查詢,。
class listmark(BaseHandler):
′′′
搜索工作微博列表
′′′
def get(self):
self.set_header("Content-Type",, "application/json")
…
class mark(BaseHandler):
′′′
基于二維空間的搜索
′′′
def get(self):
self.set_header("Content-Type","application/json")
try:
…
?。?).map-reduce計算做日志分析,。
′′′
調(diào)度生成當天用戶訪問行為
′′′
class currdayuser(BaseHandler):
def get(self):
…
′′′
調(diào)度生成當天服務(wù)運行行為
′′′
class currdayservice(BaseHandler):
def get(self):
目前這種存儲結(jié)構(gòu),解決了項目中大數(shù)據(jù)存儲和實時云計算的需求,。使用了Mongodb切片的水平動態(tài)添加,,可不中斷平臺業(yè)務(wù)系統(tǒng)的同時保障擴容后的查詢速度和云計算效能;依據(jù)切片鍵索引分片,,計算位于各切片獨立進行,,使大數(shù)據(jù)下的實時分析成為現(xiàn)實。對于高頻訪問的數(shù)據(jù)放在了Redis中,,有效地降低了磁盤I/O,,使業(yè)務(wù)系統(tǒng)響應(yīng)更為敏捷,滿足了高并發(fā)下的應(yīng)用服務(wù)的高吞吐要求,。雖然大數(shù)據(jù)的存儲和計算變得簡單,,但由于版本和技術(shù)在日新月異的變化,數(shù)據(jù)系統(tǒng)的管理工作并不輕松,。在新架構(gòu)下的運維管理還會遇到新的挑戰(zhàn)并需不斷優(yōu)化完善,。
參考文獻
[1] 田濤,常青,,邱桂蘋,,等.基于Redis的人本電子健康系統(tǒng)的設(shè)計與實現(xiàn)[J].電子世界,2013(24):137-138.
[2] 曾超宇,,李金香.Redis在高速緩存系統(tǒng)中的應(yīng)用[J].微型機與應(yīng)用,,2012(12):11-13.
[3] 何杭鋒.基于FODO算法MongoDB自動分片的改進[J].計算機技術(shù)與發(fā)展,2013(7):127-130.
[4] 霍多羅夫,,迪洛爾夫.MongoDB權(quán)威指南[M].程顯鋒譯北京:人民郵電出版社,,2011.
[5] 呂明育,李小勇.NoSQL數(shù)據(jù)庫與關(guān)系數(shù)據(jù)庫的比較分析[J].微型電腦應(yīng)用,,2011,,27(10):55-57.
[6] MongoDB features[OL]. http://www.cnblogs.com.[2011-06-01].