以下文章來源於京東零售技術 ,作者鄭思城
鏈接:https://mp.weixin.qq.com/s/OFkRnbWEa7vxm3V3OmTk-g?utm_source=tuicool&utm_medium=referral
JDNoSQL平臺是什麼
JDNoSQL平臺是一個分佈式面向列的KeyValue毫秒級存儲服務,存儲結構化數據和非機構化數據,支持隨機讀寫與更新,靈活的動態列機制,架構上支持水平擴容,提供高併發、低延遲、高可用、強一致數據庫服務,可滿足各種業務場景。完善的平臺支持,支持業務自助化建表,查看監控,在線DDL等。
1.1 JDNoSQL所處生態的位置
從上圖可以看出,JDNoSQL是一種構建在HDFS之上的分佈式、面向列的存儲系統。在需要實時讀寫、隨機訪問超大規模數據集時,可以使用JDNoSQL。
目前市面上的一些關係類型數據庫,在構建時並沒有考慮超大規模和分佈式的特點。許多商家通過複製和分區的方法來擴充數據庫使其突破單個節點的界限,但這些功能通常都是事後增加的,安裝和維護都很複雜。同時,也會影響RDBMS的特定功能,例如聯接、複雜的查詢、觸發器、視圖和外鍵約束這些操作在大型的RDBMS上的代價相當高,甚至根本無法實現。JDNoSQL從另一個角度處理伸縮性問題。它通過線性方式從下到上增加節點來進行擴展。JDNoSQL不是關係型數據庫,也不支持SQL目前可以通過JDPhoenix支持SQL,但是它有自己的特長,這是RDBMS不能處理的,JDNoSQL巧妙地將大而稀疏的表放在商用的服務器集群上。JDNoSQL有如下特點:
- 大:一個表可以有上億行,上百萬列。
- 面向列:面向列表(簇)的存儲和權限控制,列(簇)獨立檢索。
- 稀疏:對於為空(NULL)的列,並不佔用存儲空間,因此,表可以設計的非常稀疏。
- 無模式:每一行都有一個可以排序的主鍵和任意多的列,列可以根據需要動態增加,同一張表中不同的行可以有截然不同的列。
- 數據多版本:每個單元中的數據可以有多個版本,默認情況下,版本號自動分配,版本號就是單元格插入時的時間戳。
- 數據類型單一:JDNoSQL中的數據都是字符串,沒有類型。
應用場景
NoSQL在京東的使用主要涉及一下場景:
- 時序型業務(監控,IOT)
- 消息訂單(訂單/保單,聊天記錄)
- CUBE分析(實時寬表,報表,搜索推薦)
- 監控(UMP/MDC/CAP/JDH)
- Feeds流業務(評價信息,問答信息,瀑布流,朋友圈)
- AI Storage(用戶特徵、NLP語料、模型存儲)
- 時空數據(軌跡、氣象網絡)
- 金融業務(關聯分析、信用分析、風控/白條/支付/資管)
2.1 基於NoSQL的廣告實時計算系統
2.1.1 網絡廣告的幾個大特性:
相對傳統廣告,網絡廣告呈現出一些自身特點,瞭解這些特點,是網絡廣告營銷策略實質的基礎。網絡廣告的特點如下:
- 傳播範圍廣:網絡廣告的傳播範圍廣,不受時空的限制,可以通過互聯網把廣告信息全天候不間斷的傳播到世界各地。我國網民數量巨大,而且還在快速發展,這些網民有較高的消費能力,是網絡廣告的受眾,可以在世界任何地方的互聯網上隨意的瀏覽廣告,這種傳播效果是任何一種傳統媒體都無法達到的。
- 非強迫性傳播資訊:網絡廣告屬性按需廣告,具有報紙分類廣告的性質,卻不需要受眾徹底瀏覽,可以自由查詢,並根據潛在顧客的需要主動呈現和展示,這樣就節省了整個社會的注意力資源,提高了廣告的針對性和有效性。
- 受眾數據量可精準統計:傳統的媒體廣告,很難精準知道有多少人接觸了廣告信息,互聯網廣告,可以通過權威、公正的流量統計系統,精準統計每個廣告的瀏覽人數以前這些用戶查閱時長和地域分佈,從而有利於正確的評估廣告效果,進一步優化廣告投放策略。
- 靈活的時效性:互聯網廣告能按需要及時更新廣告內容。
- 強烈的交換性和感官性:網絡廣告的載體基本都是多媒體,超文本等,需要受眾對產品感興趣,僅需要點擊進一步瞭解更多、更詳細、更生動的信息,甚至還能讓消費者親自體驗產品,服務和品牌,通過虛擬現實技術,可以讓顧客身臨其境。
2.1.2 網絡廣告的數據類型:
網絡廣告相關的採集數據很多種,其中最關鍵的有四類:展現、點擊、行為、和第三方數據監控。
- 廣告展現數據
廣告展現數據是指廣告位獲得的展現的數據,一般該數據都需要發送到服務器端,用於廣告展現量(adpv)的統計分析。一般數據包含日期、用戶ID、廣告ID和IP等信息。下面是一種廣告展現的數據格式,其中JSON字段擴展:
<code>2015-01-13 19:11:55{00D81D1D-00A291-0E2300-87DBCE0DA90} {“adia”:"31769","asid": "2","aspid":"0","ptime": "14","ag":"4,5.20,26.1908","ecode": "15","type":"2","dp1": "1","adpid":"0","dsp": "0","source": "s"}61.237.239.3 天津 天津市
/<code>
- 廣告點擊數據
廣告點擊數據是指各個廣告位獲取的用戶點擊的數據,一般該數據也都需要發送到服務器端,用於廣告點擊量(adclick)的統計分析。一般點擊數據包含日期、用戶ID、廣告ID和IP等信息。下面是一種廣告點擊的數據格式,與廣告展示並沒有多少區別:
<code>2015-01-13 00:11:06{D33333C3-000C84-2345FB-DB768EC56} {"wid":"13","aid": "103297","vid":"1446779","adid": "29260","asid":"1","aspid": "1","mid":"16507","mg": "155","area":"13","dsp": "3"} 175.8.146.246 湖南省 長沙市
/<code>
- 廣告行為數據
廣告行為數據是指廣告位獲得的用戶下載、安裝或者交易的數據,一般該數據也都需要發送到服務器端,用於廣告行為(adaction)的他那個就分析。一般行為數據包含日期、用戶ID、廣告ID和IP等信息。下面是一種廣告行為的數據格式,與廣告展示數據也沒有多少區別,只是JSON擴展字段總的一些信息不同:
<code>2015-01-13 09:59:39{00567D26AD-565D01-C2238-F99000C0A0} {"adid":"234555","asid": "562", "aspid":"12","type": "1"} 120.29.183.47 福建省 寧德市
/<code>
- 第三方監控數據
為使得廣告主方便了解目標消費的網絡媒體瀏覽習慣,轉化成顧客的概率等,並且獲取公正、客觀、權威的統計信息,非常的有必要使用第三方廣告監控公司參與廣告投放的監控。而第三方的監控也會生產監控數據,包含日期、廣告ID和用戶ID等。下面是第三方監控數據的示例:
<code>2014-12-31 108A451BD3787_22E6_D020_786DF2695B {000AD54073-19DDC2-971F26-36F4119425}
/<code>
2.1.3. 廣告數據的挑戰
數據價值隨著時間的流逝而降低,所以事件出現後必須儘快對他們進行處理,最好數據出現後便立刻能對其進行處理,發生一個事件進行一次處理,而不是緩存起來成批再處理,在數據流模型中,需要處理的輸入數據(全部或是部分)並不存儲在可隨機訪問的磁盤或是內存中,他們以一個或是多個“連續數據流”的形式到達。數據不同於傳統的存儲關係模型,主要有一下幾個方面特點:
- 流中的數據元素在線到達,需要實時處理
- 系統無法控制將要處理的新到達的數據元素的順序,無論這些數據元素是在一個數據流中還在跨多個數據流;也即重放的數據流可能和上次數據流的元素順序不一致。
- 數據流的潛在大小也許是無窮無盡的。
- 一旦數據流中的某個元素經過處理,要麼被丟棄,要麼被歸檔存儲。
2.1.4 系統主要功能
該系統目前只為廣告業服務,要求廣告展現數據和廣告點擊數據能夠實時的反映到庫存系統,庫存系統可以根據現有投放量計算之後的投放策略。同時,能提供某些廣告在月每天的展現量統計,並且可以分省,市和用戶三個維度統計。在滿足上面功能的前提下,對系統性能要求延時在30秒內,支持峰值在TPS=500W的訪問請求。
2.1.5. 系統架構
根據前面的需求分析,設計目標和主要功能的要求,將整個廣告實時計算系統劃分為六層:日誌接收層、生產者層、消費隊列層、消費者層、業務邏輯層和存儲層。其中消息隊列選用京東JDQ實時數據管道,提供基於Kafka實現的高吞吐的分佈式消息隊列,供流式計算場景使用,業務邏輯層選用京東JRC 流式計算,提供基於Flink的流式計算引擎,用於流式計算,存儲選用高併發、低延遲、高可用,滿足千萬級QPS高吞吐、隨機讀寫的NoSQL分佈式存儲。架構圖如下:
- 日誌接收層
該層是數據源頭,通過日誌接收工具生產本地日誌文件。常用的接收工具包括Scribe、Nginx、Syslog-ng和Apache Http Server等,接收後這些數據流將存儲到本地磁盤文件中。
- 生產者層
該層是數據傳輸層,用於將日誌文件從本地發生到Kafka集群,實時監控指定的文件或是目錄,提取增量數據發送到Kafka集群。
- 消息隊列層
該層是Kafka集群,負責輸入數據的負載均衡、消息緩衝、同時具備高吞吐、水平擴展性好等特徵。消息隊列層之所以選擇Kafka,是因為Kafka側重吞吐量的特性,並且具備緩衝的功能。
- 消費者層
該層應用消費kafka隊列中的消息,並且將消息數輸入到業務邏輯層,是承上啟下的子層。由於業務邏輯層使用Flink框架,所有消費層需要連通Kafka和Flink兩個集群。
- 業務邏輯層
該層是實現需求的重要子層,使用Flink框架,能夠非常方便的部署不同規則的業務需求,並且可以實現快速計算。
- 存儲層
目標存儲選擇使用的分佈式存儲NoSQL,可以滿足高吞吐低延時實時更新、查找某些特定場景的的業務需求,也可以滿足水平擴展的需求。
2.1.6. 表設計
為滿足最終結果的實時查詢和週期性統計需求,將結果數據存在NoSQL中,首先需要定義表的結構。因為數據包括廣告展現和廣告點擊兩類無關聯的數據,並且業務方向也不同,所以需要創建兩個表來存儲這兩類數據的統計結構。
- 廣告實時展現統計表
廣告實時展示統計表的結構設計如下:
其中,行建的設計非常關鍵,該表包含三種類型的行建,分別以省名稱、市名稱和uid作為區分,用於更高效地統計這三個維度的數據;列族和列的數量都是1。下面是廣告實時統計表的一行數據實例,其中value字段採用十六進制字節碼錶示,是長整型。
<code>29260_{2EEBEE83-EEE4-EAE6-1F0D-A27AB14549FC}_20150117 column=pv:cnt,timestamp=1390261754783,
value= \\\\x00\\\\x00\\\\x00\\\\x00\\\\x00\\\\x00\\\\x00\\\\x02
/<code>
- 廣告實時點擊統計表
廣告實時點擊統計表的結構設如下:
相比廣告實時展現統計表,實時點擊統計表明顯簡單一些,行建只有一種類型:adid_加上日期,很常規的一種設計方案;列族和列的數據量都是1。下面是廣告實時點擊統計表的一行數據示例,其中value字段採用十六進制字節碼錶示,是長整型。
<code>36713_20150117 column=clk:cnt, timestamp=1390374472961, value=\\\\x00\\\\x00\\\\x00\\\\x00\\\\x00\\\\x00\\\\x00\\\\x06
/<code>
2.1.7. 使用NoSQL統計數據
根據上面表結構設計的描述和實現,該結構支持下面的多種實時查詢的需求:
- 某個廣告在某省的當前投放量。
- 某個廣告在某市的當前投放量。
- 某個廣告在某個用戶客戶端上的當前投放量
- 某個廣告的當前點擊量
- 某個廣告在累計一段時間內(如一個月)的某個省的歷史投放趨勢
- 某個廣告在累計一段時間內(如一個月)的某個市的歷史投放趨勢
- 某個廣告在累計一段時間內(如一個月)的某個用戶客戶端上的歷史投放趨勢
- 某個廣告在累計一段時間內(如一個月)的點擊量趨勢
以上提到的這些需求,通過封裝NoSQL客戶端可以非常方便的實現,並且滿足實時性的需求。前端數據可視化可以藉助開源的JavaScript的框架快速實現,如:echarts,highcharts, d3.js等
總結
根據Gartner的預計,全球非關係型數據庫(NoSQL)在2020~2022預計保持在30%左右高速增長,遠高於數據庫整體市場。伴隨著NoSQL和大數據技術的興起和發展,基於NoSQL及NoSQL生態構建的低成本一站式數據處理平臺正在蓬勃發展。目前支持:NoSQLAPI、關係PhoenixSQL、時序OpenTSDB、全文檢索Solr/ES、時空GeoMesa、圖HGraph、分析Spark on HBase等。隨著NoSQL的高速發展,NoSQL用戶群體越來越龐大,未來NoSQL及NoSQL生態也會更好的滿足各種業務場景。
閱讀更多 Java架構學習交流 的文章