詹利群,程海林,任曉煒
1(廣西壯族自治區(qū)氣象信息中心,南寧 530022)
2(成都信息工程大學,成都 610225)
2016年12月,全國綜合氣象信息共享平臺(簡稱CIMISS)在25個省份正式開始業(yè)務(wù)化運行,全國氣象部門初步建立了基于CIMISS的國省一致的氣象數(shù)據(jù)數(shù)據(jù)環(huán)境,各省統(tǒng)一了數(shù)據(jù)的來源、標準、流程和服務(wù)[1,2],形成了良好的業(yè)務(wù)應(yīng)用生態(tài).廣西壯族自治區(qū)氣象局圍繞CIMISS 統(tǒng)一數(shù)據(jù)環(huán)境開展核心業(yè)務(wù)系統(tǒng)的集約整合和流程再造,截至2017年底已有26個核心業(yè)務(wù)系統(tǒng)成功對接CIMISS.隨著越來越多核心業(yè)務(wù)系統(tǒng)的對接,CIMISS 成為一個數(shù)據(jù)訪問效率的瓶頸,所有對接的核心業(yè)務(wù)系統(tǒng)的數(shù)據(jù)源調(diào)用都是通過氣象數(shù)據(jù)統(tǒng)一服務(wù)接口(簡稱MUSIC)[3,4]調(diào)用CIMISS 數(shù)據(jù).MUSIC 面向氣象業(yè)務(wù)和科研,提供全國統(tǒng)一、標準、豐富的數(shù)據(jù)訪問服務(wù)和應(yīng)用編程接口(API),為國、省、地、縣各級應(yīng)用系統(tǒng)提供唯一權(quán)威的數(shù)據(jù)接入服務(wù).據(jù)2017年接口應(yīng)用統(tǒng)計分析,用戶平均每天訪問接口的次數(shù)達到35 萬次以上,實時并發(fā)數(shù)平均達到每秒50 次以上,接口耗時<1 秒的統(tǒng)計達到97.8%以上,>1 秒以上占據(jù)2.2%以上.在這些資料中,逐小時自動氣象站資料具有空間分辨率高、時間間隔短的特點,一直是氣象業(yè)務(wù)應(yīng)用中用到最多的幾種資料之一[5],對于開展預(yù)報預(yù)測、決策服務(wù)、災(zāi)害預(yù)警等氣象業(yè)務(wù)意義重大[6],用戶對該類數(shù)據(jù)的檢索效率提出了越來越高的要求.傳統(tǒng)的直接從數(shù)據(jù)庫查詢數(shù)據(jù)已經(jīng)滿足不了需求,我們迫切需要找出一種高效查詢逐小時自動氣象站數(shù)據(jù)的方法,以提高用戶服務(wù)效率.
Redis 是一種基于內(nèi)存運行并支持持久化的NoSQL數(shù)據(jù)庫,主要解決關(guān)系型數(shù)據(jù)庫高并發(fā)情況下數(shù)據(jù)處理時效問題.因為是純內(nèi)存操作,Redis 讀寫性能非常出色,每秒可以處理超過10 萬次的讀寫操作[7].
Redis 是開源的高性能Key-Value 存儲引擎,提供多種數(shù)據(jù)結(jié)構(gòu).Redis 可以用作緩存,也可以用作存儲[8].支持字符串、鏈表、集合、哈希等多種數(shù)據(jù)結(jié)構(gòu)以及豐富的編程語言,還可將緩存數(shù)據(jù)持久化,對數(shù)據(jù)的更新將異步保存到磁盤上,除此之外,也實現(xiàn)了masterslave(主從)同步,提供集群操作.
1)性能極高
Redis 直接在內(nèi)存中進行讀取及寫入,他的速度非常的快.讀取速度是110 000 次/s,寫入速度是81 000 次/s .
2)豐富的數(shù)據(jù)類型
Redis 支持二進制案例的 Strings,Lists,Hashes,Sets 及 Ordered Sets 數(shù)據(jù)類型操作.
3)原子性操作
Redis的所有操作都是原子性的,同時Redis 還支持對幾個操作全并后的原子性執(zhí)行.
4)具有豐富的特性
Redis 還支持 publish/subscribe,通知,key 過期等等特性.
Redis 最主要的應(yīng)用場景之一便是業(yè)務(wù)緩存,將一些不經(jīng)常改變但又經(jīng)常訪問的熱點數(shù)據(jù)常駐在內(nèi)存中,并在內(nèi)存中完成對數(shù)據(jù)的操作[9],有效地減少數(shù)據(jù)庫讀取次數(shù),減少數(shù)據(jù)庫壓力,提高響應(yīng)時間,增強吞吐量.
對Redis的主要操作便是對其鍵值的存取操作,根據(jù)數(shù)據(jù)結(jié)構(gòu)的不同,提供有非常豐富的操作命令.例如,對字符串和哈希結(jié)構(gòu)的簡單存取命令如下[9,10]:
1)字符串操作
存儲命令:SET key value
查詢命令:GET key
2)哈希(hash)操作
存儲命令:HSET key field value
查詢命令:HGET key field
Redis 還有設(shè)置時間過期的功能,通過EXPIRE key seconds 命令完成對鍵key的過期時間設(shè)置.
逐小時自動氣象站資料作為氣象業(yè)務(wù)部門日常觀測的重要資料之一,也是業(yè)務(wù)應(yīng)用中用到最多的幾種資料之一.通過分析CIMISS—MUSIC 氣象數(shù)據(jù)統(tǒng)一服務(wù)接口中的資料訪問情況,如圖1所示.
通過分析得出,中國地面逐小時資料是所有資料訪問中訪問次數(shù)最多的,平均每天達到10 萬次左右,占據(jù)所有資料訪問的三分之一左右.因此,對逐小時自動站資料的檢索查詢效率進行優(yōu)化提升具有非常大的必要性.
根據(jù)CIMISS 數(shù)據(jù)入庫時間分析地面自動氣象站觀測逐小時資料的到報情況,如圖2所示.
圖1 廣西CIMISS 資料訪問情況分析
圖2 2017年11月20日10時數(shù)據(jù)到報情況
可以發(fā)現(xiàn),98%以上地面自動站的數(shù)據(jù)在正點后5 分鐘內(nèi)已到報,正點十分后數(shù)據(jù)相對穩(wěn)定,不經(jīng)常改變,因此可在正點十分后將相對穩(wěn)定的數(shù)據(jù)緩存到Redis 以提升檢索效率.
為了確保Redis 緩存數(shù)據(jù)與CIMISS 數(shù)據(jù)的一致性,需要定期的將Redis 數(shù)據(jù)與CIMISS 進行同步,但如果同步頻率設(shè)置太高,如每秒或每分鐘同步一次,則從Redis 獲取數(shù)據(jù)與從CIMISS 獲取數(shù)據(jù)無差別,對檢索效率提升不大.如果同步頻率設(shè)置太低,如每10 分鐘或每半小時同步一次,緩存中的數(shù)據(jù)與CIMISS 數(shù)據(jù)的一致性差異較大.為此,需要分析CIMISS 地面自動氣象站觀測逐小時資料的數(shù)據(jù)更新規(guī)律,選取了廣西2017年的中國地面逐小時資料數(shù)據(jù),統(tǒng)計平均每k(k=1,2,3,…,10)分鐘更新次數(shù),結(jié)果如圖3所示.
圖3 CIMISS 平均每k 分鐘更新次數(shù)
需要選擇一個較高的同步頻率并且在這個頻率期間數(shù)據(jù)更新盡量少.根據(jù)逐小時資料數(shù)據(jù)的更新規(guī)律,可選擇每隔5 分鐘定期同步CIMISS的數(shù)據(jù),以此確保緩存數(shù)據(jù)的準確性.
傳統(tǒng)的關(guān)系型數(shù)據(jù)庫把邏輯模型映射為一系列表來實現(xiàn),而Redis 作為典型的Key-Value 數(shù)據(jù)庫沒有表的概念,需要將邏輯關(guān)系映射在Key 值中或者一系列的鍵值中[11].在CIMISS 系統(tǒng)中,逐小時自動氣象站資料是基于Oracle 關(guān)系數(shù)據(jù)庫進行存儲的,其檢索接口方式主要包括有按時間、地區(qū)等.根據(jù)這些業(yè)務(wù)需求,需要對數(shù)據(jù)在Redis中的存儲結(jié)構(gòu)進行策略優(yōu)化設(shè)計,Redis 數(shù)據(jù)庫設(shè)計的關(guān)鍵在于Key的設(shè)計,合理的設(shè)計能夠有效提升查詢效率和節(jié)省內(nèi)存的開銷.因此,針對實時查詢的需求,在Redis中的地面自動氣象站逐小時資料,只存儲最近1 小時的數(shù)據(jù),并通過設(shè)計業(yè)務(wù)數(shù)據(jù)庫、索引數(shù)據(jù)庫和過期時間庫以提升查詢效率和保證有效性.
業(yè)務(wù)數(shù)據(jù)是存儲地面自動氣象站逐小時資料數(shù)據(jù)的庫,包括站名、區(qū)站號、市、縣、經(jīng)度、維度、行政區(qū)代碼等基礎(chǔ)信息,并可動態(tài)擴展溫度、降水量等觀測要素值.為實現(xiàn)此功能,使用站號作為Key(固定前綴_surf1h_表示逐小時資料),使用哈希結(jié)構(gòu)作為存儲數(shù)據(jù)的結(jié)構(gòu).其存儲結(jié)構(gòu)模型如圖4所示.
圖4 逐小時資料業(yè)務(wù)數(shù)據(jù)存儲結(jié)構(gòu)
站名、站號等基礎(chǔ)信息作為通用的公共數(shù)據(jù),可在Redis 搭建完成后便初始化并長期保存,而在業(yè)務(wù)調(diào)用中,通過哈希結(jié)構(gòu)的HSET 命令來更新要素數(shù)據(jù)或動態(tài)擴展要素,使得業(yè)務(wù)數(shù)據(jù)庫能夠支撐存儲地面逐小時資料的所有要素信息.如廣西氣象自動站有2700個站,在Redis 初始化時就可將全部自動站采用站號Key 進行初始化完成,每個Key中的氣象自動站逐小時210個要素字段也可以動態(tài)初始化完成,在數(shù)據(jù)到報后通過jedis.hset("_surf1h_"+站號,"要素",value)的方式進行添加覆蓋數(shù)據(jù),從而達到數(shù)據(jù)的快速存儲操作.
……
Redis>jedis.hset("_surf1h_59431","City","南寧")
Redis>jedis.hset("_surf1h_59431","Cnty","江南區(qū)")
Redis>jedis.hset("_surf1h_59431","Lat","22.7833")
Redis>jedis.hset("_surf1h_59431","Lon","108.55")
……
為了實現(xiàn)能夠快速的按照地區(qū)、站號等要素值檢索,需要建立地區(qū)、要素值與業(yè)務(wù)數(shù)據(jù)庫中Key(即站號)的索引關(guān)系.檢索數(shù)據(jù)時,先通過索引庫檢索到符合條件的站號,以站號為Key 到業(yè)務(wù)數(shù)據(jù)庫中業(yè)務(wù)數(shù)據(jù).不同的索引方式根據(jù)不同的關(guān)系操作,采用不同的數(shù)據(jù)存儲結(jié)構(gòu).在本文中,主要建立了地區(qū)-站號索引庫,用于支持按地區(qū)檢索要素.
地區(qū)-站號索引庫采用哈希結(jié)構(gòu),頂級Key 命名為_surf1h_index_area,哈希結(jié)構(gòu)的Key 使用市(縣)名,值為區(qū)站號,多個使用逗號分隔,這部分數(shù)據(jù)經(jīng)常被訪問但幾乎不會更新,因此在搭建Redis 后即可進行初始化并長期保存.通過在初期建立_surf1h_index_area的Key,將廣西14個地市和每個地市的相對應(yīng)的區(qū)站號建立起來,其存儲結(jié)構(gòu)如圖5所示.
圖5 逐小時資料地區(qū)-站號索引庫存儲結(jié)構(gòu)
為保證緩存在業(yè)務(wù)數(shù)據(jù)庫中數(shù)據(jù)與CIMISS中的數(shù)據(jù)是準確一致的,可以通過設(shè)計過期時間庫來確保有效性.過期時間的設(shè)定與檢索查詢效率和數(shù)據(jù)一致性緊密相關(guān),過期時間太短,則會頻繁的查詢CIMISS,效率提升不明顯,過期時間太長,緩存中的數(shù)據(jù)又與CIMISS 差異較大,不適合業(yè)務(wù)應(yīng)用.Redis 本身擁有設(shè)置時間過期的功能,即對存儲在Redis 數(shù)據(jù)庫中的值可以設(shè)置一個過期時間.根據(jù)對2.2 自動氣象站資料的時間特性進行分析,在正點10 分時開始將較穩(wěn)定的數(shù)據(jù)在Redis 進行緩存,并每隔5 分與CIMISS 數(shù)據(jù)進行一次同步,即Redis中的數(shù)據(jù)只有在5 分鐘內(nèi)是有效的,當超出該時間后,過期時間庫中的該要素信息便會被移除,此時即表示業(yè)務(wù)數(shù)據(jù)庫該要素的數(shù)據(jù)已過期.
數(shù)據(jù)寫入Redis 業(yè)務(wù)數(shù)據(jù)庫初期,程序員建立散列類型,通過HSET 命令逐要素寫入.設(shè)計過程中又通過HMSET 命令同時設(shè)置多個要素字段寫入,程序代碼比之前簡潔.另外,通過要使用Redis 集群存儲資料首先要初始化線程類:
new RedisTestThread("redis"+i,element,admin-Code).start()
將不同的要素、地區(qū)數(shù)據(jù)進行初始化.在線程類中實現(xiàn)將不同的站號進行初始化,根據(jù)資料要素的不同站號,通過jedis.hmset(key,dataMap)進行數(shù)據(jù)設(shè)置,其中Key 為"_surf1h_"+站號,dataMap 為站號下對應(yīng)的業(yè)務(wù)數(shù)據(jù).
最后設(shè)置數(shù)據(jù)過期時間jedis.expire(key,Time).
省、市、縣三級用戶對自動氣象站逐小時數(shù)據(jù)的查詢主要通過地區(qū)行政編碼進行分類查詢,索引庫的建立,可以通過采用地區(qū)行政編碼作為地區(qū)分類.首先建立所有地區(qū)分類的集合,如“450000”代表全廣西,則該索引下的站號為全廣西的自動站站號,“450100”代表南寧市,則“450100”索引下存放整個南寧市的自動站站號.通過循環(huán)設(shè)置全廣西各區(qū)市縣的站號索引.在程序設(shè)計上先定義一個HashMap 用來存放行政編碼對應(yīng)的站號信息,然后通過jedis.hmset(_surf1h_index_area,map)存放業(yè)務(wù)數(shù)據(jù),jedis.expire(_surf1h_index_area,Time)設(shè)置過期時間,達到按地區(qū)行政編碼優(yōu)化索引庫提升索引查詢性能.
完成業(yè)務(wù)數(shù)據(jù)庫、索引庫及過期時間庫存儲設(shè)計后,開始通過程序?qū)⒅鹦r自動氣象站資料及相關(guān)的輔助信息存入庫中,資料查詢流程如圖6所示.
圖6 基于Redis的逐小時資料檢索查詢流程
主要包括以下三種情況:
1)請求時間在正點后十分鐘內(nèi)
根據(jù)自動氣象站觀測規(guī)范,自動氣象站觀測數(shù)據(jù)在正點觀測后,數(shù)據(jù)立即從分布在全區(qū)各個觀測站發(fā)回觀測數(shù)據(jù)文件.通常正點后的2-4 分鐘是地面逐小時觀測數(shù)據(jù)入庫的高峰期,在這個時間內(nèi)數(shù)據(jù)解碼入庫的更新頻度非常高,將數(shù)據(jù)緩存到Redis中沒有意義,因此這個時間內(nèi)的數(shù)據(jù)請求均是通過接口直接訪問CIMISS 獲取數(shù)據(jù)并返回.
2)請求時間在正點十分后,Redis 緩存數(shù)據(jù)已過期
此時CIMISS中數(shù)據(jù)相對穩(wěn)定,但Redis中緩存數(shù)據(jù)已過期,因此需要重新訪問CIMISS 以獲取最新有效數(shù)據(jù),獲取數(shù)據(jù)后更新業(yè)務(wù)數(shù)據(jù)庫中相應(yīng)要素的值,同時重新設(shè)置該要素的過期時間,如設(shè)置為5 分鐘,最后返回數(shù)據(jù).
3)請求時間在正點十分后,Redis 緩存數(shù)據(jù)未過期
此時緩存在Redis中的數(shù)據(jù)為有效數(shù)據(jù),首先通過查詢條件,在索引庫中進行相應(yīng)的關(guān)系查詢篩選出符合條件的站點數(shù)據(jù),然后通過站號從業(yè)務(wù)數(shù)據(jù)庫中檢索數(shù)據(jù)并返回.
在程序設(shè)計上使用jedis.hget(areaIndexKey,admin-Code),根據(jù)地區(qū)行政編碼進行數(shù)據(jù)分類獲取站號索引,得到該地區(qū)的所有站點,再通過循環(huán)站點獲取業(yè)務(wù)數(shù)據(jù):
通過上述代碼可查詢得到相應(yīng)的業(yè)務(wù)數(shù)據(jù)
1)搭建Redis 集群
使用Redis 集群不僅可以擴大緩存數(shù)據(jù)量,也能通過主從復(fù)制機制避免單節(jié)點故障導(dǎo)致無法繼續(xù)工作.在本文中,搭建3 臺服務(wù)器6個節(jié)點的Redis 集群,部署環(huán)境如表1所示.
表1 Redis 集群配置
2)建立模擬訪問
使用Jedis(Redis的Java 版本的客戶端實現(xiàn))實現(xiàn)對Redis 集群的操作[12],編寫Java 程序執(zhí)行訪問請求,使用多線程等技術(shù),模擬實現(xiàn)對CIMISS 以及對Redis的檢索查詢操作.
選取地面中中國地面逐小時資料進行試驗分析,并選取了2018年11月26~30日每天上午7-10時和下午17-22時(業(yè)務(wù)高峰期)對實時數(shù)據(jù)(1 小時內(nèi))進行緩存.資料包括站號、站名、溫度、降水等210個要素,如表2所示.
表2 中國地面逐小時資料數(shù)據(jù)結(jié)構(gòu)
為實現(xiàn)對基于Redis的逐小時自動氣象站資料存儲的查詢效率進行分析,設(shè)計兩組實驗?zāi)M訪問最近一小時的逐小時自動氣象站資料,實驗周期為2018年11月26~30日每天上午7-10時和下午17-22時,訪問頻率為每隔一分鐘進行一次請求,實驗詳細設(shè)計如表3所示.
表3 實驗組設(shè)計
實驗選擇檢索南寧市最近一小時降雨量為例,通過記錄每次開始執(zhí)行訪問至獲取到數(shù)據(jù)時的時間差(即執(zhí)行一次檢索數(shù)據(jù)的耗時,時間單位為ms)作為實驗結(jié)果.
1)查詢效率分析
因正點后前十分CIMISS 組合Redis 組均是直接訪問CIMISS 接口,效率一致,不必分析.選擇在正點十分后模擬基于Redis 和CIMISS的數(shù)據(jù)查詢,每分鐘調(diào)用一次查詢,分別記錄每次查詢耗時,結(jié)果如圖7所示.
可以看出,在正點十分后,直接從CIMISS 查詢的耗時總體在500 ms 左右,而Redis的查詢耗時大多數(shù)時候在100 ms 左右,每隔5 分鐘因需從CIMISS 進行數(shù)據(jù)同步而耗時在500 ms 左右.從Redis 查詢平均耗時0.2 秒左右,CIMISS 組平均耗時0.5 秒左右,前者具有更高的查詢效率,是后者的兩倍以上.
圖7 基于Redis 與CIMISS 查詢耗時對比
2)數(shù)據(jù)一致性分析
緩存中的數(shù)據(jù)包括中國地面逐小時資料共210個要素,為確保數(shù)據(jù)的準備,通過對比2018年11月26~30日每天上午7-10時和下午17-22時每分鐘從Redis 取出的要素值與CIMISS中的要素值,記錄值相同的要素個數(shù),實驗期間平均結(jié)果如圖8所示.
圖8 Redis 與CIMISS 數(shù)據(jù)值相同的要素個數(shù)統(tǒng)計圖
通過分析,中國地面逐小時資料共210個要素在1 小時內(nèi)緩存數(shù)據(jù)與CIMISS 數(shù)據(jù)的一致性達到了99%以上,能確保數(shù)據(jù)的完整性,滿足業(yè)務(wù)應(yīng)用要求.
本文利用Redis 是開源的高性能Key-Value 存儲引擎,提供多種數(shù)據(jù)結(jié)構(gòu)利用Redis 開源高效內(nèi)存數(shù)據(jù)庫的特點,結(jié)合地面自動氣象站逐小時資料在實際業(yè)務(wù)中的應(yīng)用,通過Redis 數(shù)據(jù)庫結(jié)構(gòu)模型設(shè)計和優(yōu)化、并通過實驗對Redis 提高了逐小時自動氣象站資料的檢索效率和數(shù)據(jù)一致性進行驗證,為用戶在不同氣象資料查詢檢索方面提供了一套可操作的技術(shù)參考樣例.由于自動氣象站觀測資料更正報等實際情況,可能導(dǎo)致緩存在Redis中的數(shù)據(jù)的及時性和一致性降低,這方面可以考慮采用基于消息的機制更新緩存數(shù)據(jù)或縮短緩存時間等來這個解決問題.在氣象業(yè)務(wù)中,還存在很多對查詢要求較高的觀測資料,本文提出的逐小時地面自動站資料數(shù)據(jù)結(jié)構(gòu)模型并通過Redis 進行緩存能有效的提升檢索效率,并可以應(yīng)用到其它資料的檢索調(diào)用業(yè)務(wù)場景中,具有較好的推廣應(yīng)用價值.