mongodb 查多个不等于_高可用架构之商城的mongodb设计分析
一. mongodb商品數據異構和聚合設計
問題起因
對于商品詳情頁的數據來源于如下主要服務:
1、商品基本信息
2、商品圖片服務
3、促銷服務
4、庫存狀態/配送至服務
5、廣告詞服務
6、預售服務
7、評價服務
8、試用服務
9、優惠券服務
10、推薦服務
11、商品介紹服務
12、商品分類,商品品類相關的信息
那么問題來了, 現在要給前端返回商品詳情數據, 要去這么多地方查嗎?
答案是,不需要的。
因為,我們可以將這些數據存在一個mongodb文檔中, 一個商品的商品詳情頁的所有信息只需要一條數據就存下來了。雖然mongodb和redis都是利用內存加 速,且查詢速度都很快,但還是有一定的區別。
MongoDB 和redis的區別:
MongoDB 更類似 MySQL,支持字段索引、where等查詢,其優勢在于查詢功能比較強大,擅長查詢 JSON 數據,且能存儲海量數據,但是不支持 事務。
Redis 是一個開源(BSD許可)的,內存中的數據結構存儲系統,支持多種類型的數據結構,可用作數據庫,高速緩存和消息隊列代理。
具體如何設計呢?
設計圖:
1. 如上所述,商品詳情頁的相關數據來源于12個不同的地方。當這12個地方的相關數據發生變化時, 我們把數據推送到rabbitmq。
2. 數據聚合Worker去rabbitmq里面把消息取出來,然后把數據存入mongodb。
3. 商品詳情頁數據的呈現只需要查詢mongodb數據庫中的一條即可。
為什么要數據據異構聚合??除了大大幅提升升訪問性性能和簡化訪問過程。。其中還還貫穿了了服務閉閉環的的思。
數據閉環
數據異構系統。比如商品詳情頁的庫存顯示,我們不是去調用庫存服務獲取,而是庫存服務通過rabbitmq同步到商品詳情服務的mongodb的異構數 據中。對于這些數據我們可以做異構,異構過來我們只依賴于自己不依賴其他人。其他人服務出問題了,抖動了或者響應慢了,對我們是沒有影響的。假設我們在設計頁面的時候有很多服務依賴于別人,出問題之后肯定先找我們。找我們的時候我們又需要去聯系其他的部門,就會存在溝通的問 題。
.2. mongodb急速查詢附近用戶之設計
場景:
首先,我們的app能夠獲取買家所在位置的經緯度,其次,我們的數據庫存了商家店鋪的經緯度。
需要實現的需求:現在我們的用戶要在我們商城app上由遠及近查看他附近的商家。
那么后端要如何計算出該買家附近有哪些商家呢?
方案1:基于MySQL數據庫
MySQL的使用非常簡單。對于大部分已經使用MySQL的網站來說,使用這種方案沒有任何遷移和部署成本,而在MySQL中查詢“最近的人”也僅需一條SQL即可。
SELECT id, ( 6371 * acos( cos( radians(37) ) * cos( radians( lat ) ) * cos( radians ( lng ) - radians(-122) ) + sin( radians(37) ) * sin( radians( lat ) ) ) ) AS distance FROM places HAVING distance < 25 ORDER BY distance LIMIT 0 , 100;
注:這條SQL查詢的是在lat,lng這個坐標附近的目標,并且按距離正序排列,SQL中的distance單位為公里,但使用SQL語句進行查詢的缺點也顯而易見,每條SQL 的計算量都會非常大,有時候要十幾秒才能出結果,性能將會是嚴重的問題。
方案1的結果:
最近數據庫怎么cpu和內存老是一不留意就跑滿了,甚至宕機,經查明,原來就是這貨的鍋。
方案2:mongodb geo方案
mongodb geo方案:
對于我們的需求,在MongoDB只需一個命令即可得到所需要的結果:
db.runCommand( { geoNear: "places", near: [ 121.4905, 31.2646 ], num:100 })
查詢結果默認將會由近到遠排序,而且查詢結果也包含目標點對象、距離目標點的距離等信息。
由于geoNear是MongoDB原生支持的查詢函數,所以性能上也做到了高度的優化,完全可以應付生產環境的壓力。
3 mongodb(集群+副本集)架構
從圖中可以看到有四個組件:route-mongos、config server、shard、secondary。
route-mongos,數據庫集群請求的入口,所有的請求都通過mongos進行協調,不需要在應用程序添加一個路由選擇器,mongos自己就是一個請求分發中心,它負責把 對應的數據請求請求轉發到對應的shard服務器上。在生產環境通常有多mongos作為請求的入口,防止其中一個掛掉所有的mongodb請求都沒有辦法操作。
config server,顧名思義為配置服務器,存儲所有數據庫元信息(路由、分片)的配置。mongos本身沒有物理存儲分片服務器和數據路由信息,只是緩存在內存 里,配置服務器則實際存儲這些數據。mongos第一次啟動或者關掉重啟就會從 config server 加載配置信息,以后如果配置服務器信息變化會通知到所有的 mongos 更新自己的狀態,這樣 mongos 就能繼續準確路由。在生產環境通常有多個 config server 配置服務器,因為它存儲了分片路由的元數據,防止數據丟 失!
shard,分片(sharding)是指將數據庫拆分,將其分散在不同的機器上的過程。將數據分散到不同的機器上,不需要功能強大的服務器就可以存儲更多的數據和處 理更大的負載。基本思想就是將集合切成小塊,這些塊分散到若干片里,每個片只負責總數據的一部分,最后通過一個均衡器來對各個分片進行均衡(數據遷 移)。
secondary,中文翻譯副本集,其實就是shard的備份,防止shard掛掉之后數據丟失。復制提供了數據的冗余備份,并在多個服務器上存儲數據副本,提高了數據 的可用性, 并可以保證數據的安全性。
仲裁者(Arbiter),是復制集中的一個MongoDB實例,它并不保存數據。仲裁節點使用最小的資源并且不要求硬件設備,不能將Arbiter部署在同一個數據集節點 中,可以部署在其他應用服務器或者監視服務器中,也可部署在單獨的虛擬機中。為了確保復制集中有奇數的投票成員(包括primary),需要添加仲裁節點做為 投票,否則primary不能運行時不會自動切換primary。
簡單了解之后,我們可以這樣總結一下,應用請求mongos來操作mongodb的增刪改查,配置服務器存儲數據庫元信息,并且和mongos做同步,數據最終存入在 shard(分片)上,為了防止數據丟失同步在副本集中存儲了一份,仲裁在數據存儲到分片的時候決定存儲到哪個節點。
總結
以上是生活随笔為你收集整理的mongodb 查多个不等于_高可用架构之商城的mongodb设计分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 什么叫俚语(市井俚语什么意思)
- 下一篇: 视频捕捉软件经典使用教程