nosql 資料庫筆記

來源:互聯網
上載者:User
文章目錄
  • I/O的五分鐘法則
  • 不要刪除資料
  • Hadoop之Hbase

 

I/O的五分鐘法則在 1987 年,Jim Gray 與 Gianfranco Putzolu 發表了這個"五分鐘法則"的觀點,簡而言之,如果一條記錄頻繁被訪問,就應該放到記憶體裡,否則的話就應該待在硬碟上按需要再訪問。這個臨界點就是五分鐘。 看上去像一條經驗性的法則,實際上五分鐘的評估標準是根據投入成本判斷的,根據當時的硬體發展水準,在記憶體中保持 1KB 的資料成本相當於硬碟中存據 400 秒的開銷(接近五分鐘)。這個法則在 1997 年左右的時候進行過一次回顧,證實了五分鐘法則依然有效(硬碟、記憶體實際上沒有質的飛躍),而這次的回顧則是針對 SSD 這個"新的舊硬體"可能帶來的影響。隨著快閃記憶體時代的來臨,五分鐘法則一分為二:是把 SSD 當成較慢的記憶體(extended buffer pool )使用還是當成較快的硬碟(extended disk)使用。小記憶體頁在記憶體和快閃記憶體之間的移動對比大記憶體頁在快閃記憶體和磁碟之間的移動。在這個法則首次提出的 20 年之後,在快閃記憶體時代,5 分鐘法則依然有效,只不過適合更大的記憶體頁(適合 64KB 的頁,這個頁大小的變化恰恰體現了電腦硬體工藝的發展,以及頻寬、延時)。不要刪除資料
Oren Eini(又名Ayende Rahien)建議開發人員盡量避免資料庫的虛刪除操作,讀者可能因此認為硬刪除是合理的選擇。作為對Ayende文章的回應,Udi Dahan強烈建議完全避免資料刪除。

所謂虛刪除主張在表中增加一個IsDeleted列以保持資料完整。如果某一行設定了IsDeleted標誌列,那麼這一行就被認為是已刪除的。Ayende覺得這種方法“簡單、容易理解、容易實現、容易溝通”,但“往往是錯的”。
為了代替IsDeleted標誌,Dahan建議用一個代表相關資料狀態的欄位:有效、停用、取消、棄置等等。使用者可以藉助這樣一個狀態欄位回顧過去的資料,作為決策的依據。

刪除資料除了破壞資料一致性,還有其它負面的後果。Dahan建議把所有資料都留在資料庫裡:“別刪除。就是別
刪除。”

手段篇一致性雜湊要求分布式架構的發展說起。

第一階段考慮到單伺服器不能承載,因此使用了分布式架構,最初的演算法為 hash() mod n, hash()通常取使用者ID,n為節點數。此方法容易實現且能夠滿足運營要求。缺點是當單點發生故障時,系統無法自動回復。

 

第二階段
為瞭解決單點故障,使用 hash() mod (n/2), 這樣任意一個使用者都有2個伺服器備選,可由client隨機選取。由於不同伺服器之間的使用者需要彼此互動,所以所有的伺服器需要確切的知道使用者所在的位置。因此使用者位置被儲存到memcached中。

當一台發生故障,client可以自動切換到對應backup,由於切換前另外1台沒有使用者的session,因此需要client自行重新登入。

 

這個階段的設計存在以下問題
負載不均衡,尤其是單台發生故障後剩下一台會壓力過大。
不能動態增刪節點
節點發生故障時需要client重新登入

第三階段
打算去掉硬式編碼hash() mod n 演算法,改用一致性雜湊(consistent hashing)分布
假如採用Dynamo中的strategy 1
我們把每台server分成v個虛擬節點,再把所有虛擬節點(n*v)隨機分配到一致性雜湊的圓環上,這樣所有的使用者從自己圓環上的位置順時針往下取到第一個vnode就是自己所屬節點。當此節點存在故障時,再順時針取下一個作為替代節點。

 

 



優點:發生單點故障時負載會均衡分散到其他所有節點,程式實現也比較優雅。

演算法的選擇

不同的雜湊演算法可以導致資料分布的不同位置,如果十分均勻,那麼一次MapReduce就涉及節點較多,但熱點均勻,方便管理。反之,熱點不均,會大致機器效率發揮不完全。Paxos

paxos是一種處理一致性的手段,可以理解為事務吧。
其他的手段不要Google GFS使用的Chubby的Lock service。我不大喜歡那種重型的設計就不費筆墨了。

背景當規模越來越大的時候。


一、Master/slave

這個是多機房資料訪問最常用的方案,一般的需求用此方案即可。因此大家也經常提到“premature optimization is the root of all evil”。
優點:利用mysql replication即可實現,成熟穩定。
缺點:寫操作存在單點故障,master壞掉之後slave不能寫。另外slave的延遲也是個困擾人的小問題。

二、Multi-master

Multi-master指一個系統存在多個master, 每個master都具有read-write能力,需根據時間戳記或商務邏輯合并版本。比如分布式版本管理系統git可以理解成multi-master模式。具備最終一致性。多版本資料修改可以借鑒Dynamo的vector clock等方法。

優點:解決了單點故障。
缺點:不易實現一致性,合并版本的邏輯複雜。
三、Two-phase commit(2PC)

Two-phase commit是一個比較簡單的一致性演算法。由於一致性演算法通常用神話(如Paxos的The Part-Time Parliament論文)來比喻容易理解,下面也舉個類似神話的例子。

某班要組織一個同學聚會,前提條件是所有參與者同意則活動舉行,任意一人拒絕則活動取消。用2PC演算法來執行過程如下

Phase 1

Prepare: 召集人(coordinator)打電話給所有參與者(participant) ,同時告知參與者清單。
Proposal: 提出周六2pm-5pm舉辦活動。
Vote: participant需vote結果給coordinator:accept or reject。
Block: 如果accept, participant鎖住周六2pm-5pm的時間,不再接受其他請求。
Phase 2

Commit: 如果所有參與者都同意,召集人coodinator通知所有參與者commit, 否則通知abort,participant解除鎖定。
Failure 典型失敗情況分析

Participant failure:
任一參與者無響應,coordinator直接執行abort
Coordinator failure:
Takeover: 如果participant一段時間沒收到cooridnator確認(commit/abort),則認為coordinator不在了。這時候可自動成為Coordinator備份(watchdog)
Query: watchdog根據phase 1接收的participant列表發起query
Vote: 所有participant回複vote結果給watchdog, accept or reject
Commit: 如果所有都同意,則commit, 否則abort。

優點:實現簡單。
缺點:所有參與者需要阻塞(block),throughput低;無容錯機制,一節點失敗則整個事務失敗。

四、Three-phase commit (3PC)

Three-phase commit是一個2PC的改進版。2PC有一些很明顯的缺點,比如在coordinator做出commit決策並開始發送commit之後,某個participant突然crash,這時候沒法abort transaction, 這時候叢集內實際上就存在不一致的情況,crash恢複後的節點跟其他節點資料是不同的。因此3PC將2PC的commit的過程1分為2,分成preCommit及commit, 。

 


(圖片來源:http://en.wikipedia.org/wiki/File:Three-phase_commit_diagram.png)

從圖來看,cohorts(participant)收到preCommit之後,如果沒收到commit, 預設也執行commit, 即圖上的timeout cause commit。

如果coodinator發送了一半preCommit crash, watchdog接管之後通過query, 如果有任一節點收到commit, 或者全部節點收到preCommit, 則可繼續commit, 否則abort。

優點:允許發生單點故障後繼續達成一致。
缺點:網路分離問題,比如preCommit訊息發送後突然兩個機房斷開,這時候coodinator所在機房會abort, 另外剩餘replicas機房會commit。

Google Chubby的作者Mike Burrows說過, “there is only one consensus protocol, and that’s Paxos” – all other approaches are just broken versions of Paxos. 意即“世上只有一種一致性演算法,那就是Paxos”,所有其他一致性演算法都是Paxos演算法的不完整版。相比2PC/3PC, Paxos演算法的改進
P1a. 每次Paxos執行個體執行都分配一個編號,編號需要遞增,每個replica不接受比當前最大編號小的提案
P2. 一旦一個 value v 被replica通過,那麼之後任何再獲批准的 value 必須是 v,即沒有拜占庭將軍(Byzantine)問題。拿上面請客的比喻來說,就是一個參與者一旦accept周六2pm-5pm的proposal, 就不能改變主意。以後不管誰來問都是accept這個value。
一個proposal只需要多數派同意即可通過。因此比2PC/3PC更靈活,在一個2f+1個節點的叢集中,允許有f個節點不可用。

另外Paxos還有很多約束的細節,特別是Google的chubby從工程實現的角度將Paxos的細節補充得非常完整。比如如何避免Byzantine問題,由於節點的持久儲存可能會發生故障,Byzantine問題會導致Paxos演算法P2約束失效。

DHT

Distributed hash tableMap Reduce Execution

Map Reduce已經爛大街了,不過還是要提一下。
參見:http://zh.wikipedia.org/wiki/MapReduce

Handling Deletes但我們執行刪除操作的時候必須非常謹慎,以防丟失掉相應的版本資訊。

通常我們給一個Object標註上"已刪除"的標籤。在足夠的時間之後,我們在確保版本一致的情況下可以將它徹底刪除。回收他的空間。

列存描述

資料庫以行、列的二維表的形式儲存資料,但是卻以一維字串的方式儲存,例如以下的一個表:

 

EmpId Lastname Firstname Salary
1 Smith Joe 40000
2 Jones Mary 50000
3 Johnson Cathy 44000

這個簡單的表包括員工代碼(EmpId), 姓名欄位(Lastname and Firstname)及工資(Salary).

這個表格儲存體在電腦的記憶體(RAM)和儲存(硬碟)中。雖然記憶體和硬碟在機制上不同,電腦的作業系統是以同樣的方式儲存的。資料庫必須把這個二維表格儲存體在一系列一維的“位元組”中,又作業系統寫到記憶體或硬碟中。

行式資料庫把一行中的資料值串在一起儲存起來,然後再儲存下一行的資料,以此類推。1,Smith,Joe,40000;2,Jones,Mary,50000;3,Johnson,Cathy,44000;

列式資料庫把一列中的資料值串在一起儲存起來,然後再儲存下一列的資料,以此類推。1,2,3;Smith,Jones,Johnson;Joe,Mary,Cathy;40000,50000,44000;

特點

  • 良好的壓縮比。由於大多數資料庫設計都有冗餘,如此一來,壓縮比非常高,把40多M的資料匯入infobright,沒想到資料檔案只有1M多
  • 列上的計算非常的快。
  • 方便MapReduce和Key-value模型的融合
  • 讀取整行的資料較慢,但部分資料較快

 

亞資料庫

我發明的新概念,就是稱不上資料庫但有一些資料庫的特徵。可以指緩衝。
MemCached

Memcached是danga.com(運營LiveJournal的技術團隊)開發的一套分布式記憶體對象緩衝系統,用於在動態系統中減少資料庫 負載,提升效能。
特點

  • 協議簡單
  • 基於libevent的事件處理
  • 內建記憶體儲存方式
  • memcached不互相通訊的分布式

Memcached處理的原子是每一個(key,value)對(以下簡稱kv對),key會通過一個hash演算法轉化成hash-key,便於尋找、對比以及做到儘可能的散列。同時,memcached用的是一個二級散列,通過一張大hash表來維護。

Memcached有兩個核心組件組成:服務端(ms)和用戶端(mc),在一個memcached的查詢中,mc先通過計算key的hash值來 確定kv對所處在的ms位置。當ms確定後,用戶端就會發送一個查詢請求給對應的ms,讓它來尋找確切的資料。因為這之間沒有互動以及多播協議,所以 memcached互動帶給網路的影響是最小化的。

記憶體配置

預設情況下,ms是用一個內建的叫“塊分配器”的組件來分配記憶體的。捨棄c++標準的malloc/free的記憶體配置,而採用塊分配器的主要目的 是為了避免記憶體片段,否則作業系統要花費更多時間來尋找這些邏輯上連續的記憶體塊(實際上是斷開的)。用了塊分配器,ms會輪流的對記憶體進行大塊的分配,並 不斷重用。當然由於塊的大小各不相同,當資料大小和塊大小不太相符的情況下,還是有可能導致記憶體的浪費。

同時,ms對key和data都有相應的限制,key的長度不能超過250位元組,data也不能超過塊大小的限制 --- 1MB。
因為mc所使用的hash演算法,並不會考慮到每個ms的記憶體大小。理論上mc會分配機率上等量的kv對給每個ms,這樣如果每個ms的記憶體都不太一樣,那 可能會導致記憶體使用量率的降低。所以一種替代的解決方案是,根據每個ms的記憶體大小,找出他們的最大公約數,然後在每個ms上開n個容量=最大公約數的 instance,這樣就等於擁有了多個容量大小一樣的子ms,從而提供整體的記憶體使用量率。

緩衝策略

當ms的hash表滿了之後,新的插入資料會替代老的資料,更新的策略是LRU(最近最少使用),以及每個kv對的有效時限。Kv對儲存有效時限是在mc端由app設定並作為參數傳給ms的。

同時ms採用是偷懶替代法,ms不會開額外的進程來即時監測過時的kv對並刪除,而是若且唯若,新來一個插入的資料,而此時又沒有多餘的空間放了,才會進行清除動作。

快取資料庫查詢

現在memcached最流行的一種使用方式是快取資料庫查詢,下面舉一個簡單例子說明:

App需要得到userid=xxx的使用者資訊,對應的查詢語句類似:

“SELECT * FROM users WHERE userid = xxx”

App先去問cache,有沒有“user:userid”(key定義可預先定義約束好)的資料,如果有,返回資料;如果沒有,App會從資料庫中讀取資料,並調用cache的add函數,把資料加入cache中。

當取的資料需要更新,app會調用cache的update函數,來保持資料庫與cache的資料同步。

從上面的例子我們也可以發現,一旦資料庫的資料發現變化,我們一定要及時更新cache中的資料,來保證app讀到的是同步的正確資料。當然我們可 以通過定時器方式記錄下cache中資料的失效時間,時間一過就會激發事件對cache進行更新,但這之間總會有時間上的延遲,導致app可能從 cache讀到髒資料,這也被稱為狗洞問題。(以後我會專門描述研究這個問題)

資料冗餘與故障預防

從設計角度上,memcached是沒有資料冗餘環節的,它本身就是一個大規模的高效能cache層,加入資料冗餘所能帶來的只有設計的複雜性和提高系統的開支。

當一個ms上丟失了資料之後,app還是可以從資料庫中取得資料。不過更謹慎的做法是在某些ms不能正常工作時,提供額外的ms來支援cache,這樣就不會因為app從cache中取不到資料而一下子給資料庫帶來過大的負載。

同時為了減少某台ms故障所帶來的影響,可以使用“熱備份”方案,就是用一台新的ms來取代有問題的ms,當然新的ms還是要用原來ms的IP地址,大不了資料重新裝載一遍。

另外一種方式,就是提高你ms的節點數,然後mc會即時偵查每個節點的狀態,如果發現某個節點長時間沒有響應,就會從mc的可用server列表裡 刪除,並對server節點進行重新hash定位。當然這樣也會造成的問題是,原本key儲存在B上,變成儲存在C上了。所以此方案本身也有其弱點,最好 能和“熱備份”方案結合使用,就可以使故障造成的影響最小化。

Memcached用戶端(mc)

 

Memcached用戶端有各種語言的版本供大家使用,包括java,c,php,.net等等,具體可參見memcached api page [2]。
大家可以根據自己項目的需要,選擇合適的用戶端來整合。

緩衝式的Web應用程式架構

有了緩衝的支援,我們可以在傳統的app層和db層之間加入cache層,每個app伺服器都可以綁定一個mc,每次資料的讀取都可以從ms中取得,如果 沒有,再從db層讀取。而當資料要進行更新時,除了要發送update的sql給db層,同時也要將更新的資料發給mc,讓mc去更新ms中的資料。 

效能測試

Memcached 寫速度
平均速度: 16222 次/秒
最大速度 18799 次/秒

Memcached 讀速度
平均速度: 20971 次/秒
最大速度 22497 次/秒

Memcachedb 寫速度
平均速度: 8958 次/秒
最大速度 10480 次/秒

Memcachedb 讀速度
平均速度: 6871 次/秒
最大速度 12542 次/秒

 

 

 

dbcached

● dbcached 是一款基於 Memcached 和 NMDB 的分布式 key-value 資料庫記憶體緩衝系統。
● dbcached = Memcached + 持久化儲存管理器 + NMDB 用戶端介面
● Memcached 是一款高效能的,分布式的記憶體對象緩衝系統,用於在Live App中減少資料庫負載,提升訪問速度。
● NMDB 是一款多協議網路資料庫(dbm類)管理器,它由記憶體緩衝和磁碟儲存兩部分構成,使用 QDBM 或 Berkeley DB 作為後端資料庫。
● QDBM 是一個管理資料庫的常式庫,它參照 GDBM 為了下述三點而被開發:更高的處理速度,更小的資料庫檔案大小,和更簡單的API。QDBM 讀寫速度比 Berkeley DB 要快,詳細速度比較見《Report of Benchmark Test》。

Memcached 和 dbcached 在功能上一樣嗎?

 

● 相容:Memcached 能做的,dbcached 都能做。除此之外,dbcached 還將“Memcached、持久化儲存管理器、NMDB 用戶端介面”在一個程式中結合起來,對任何原有 Memcached 用戶端來講,dbcached 仍舊是個 Memcached 記憶體對象緩衝系統,但是,它的資料可以持久儲存到本機或其它伺服器上的 QDBM 或 Berkeley DB 資料庫中。
● 效能:前端 dbcached 的並發處理能力跟 Memcached 相同;後端 NMDB 跟 Memcached 一樣,採用了libevent 進行網路IO處理,擁有自己的記憶體緩衝機制,效能不相上下。
● 寫入:當“dbcached 的 Memcached 部分”接收到一個 set(add/replace/...) 請求並儲存 key-value 資料到記憶體中後,“dbcached 持久化儲存管理器”能夠將 key-value 資料通過“NMDB 用戶端介面”儲存到 QDBM 或 Berkeley DB 資料庫中。
● 速度:如果加上“-z”參數,採用 UDP 協議“只發送不接收”模式將 set(add/replace/...) 命令寫入的資料傳遞給 NMDB 伺服器端,對 Memcache 用戶端寫速度的影響幾乎可以忽略不計。在千兆網卡、同一交換器下伺服器之間的 UDP 傳輸丟包率微乎其微。在命中的情況下,讀取資料的速度跟普通的 Memcached 無差別,速度一樣快。
● 讀取:當“dbcached 的 Memcached 部分”接收到一個 get(incr/decr/...) 請求後,如果“dbcached 的 Memcached 部分”查詢自身的記憶體緩衝未命中,則“dbcached 持久化儲存管理器”會通過“NMDB 用戶端介面”從 QDBM 或 Berkeley DB 資料庫中取出資料,返回給使用者,然後儲存到 Memcached 記憶體中。如果有使用者再次請求這個 key,則會直接從 Memcached 記憶體中返回 Value 值。
● 持久:使用 dbcached,不用擔心 Memcached 伺服器死機、重啟而導致資料丟失。
● 變更:使用 dbcached,即使因為容錯移轉,添加、減少 Memcached 伺服器節點而破壞了“key 資訊”與對應“Memcached 伺服器”的映射關係也不怕。
● 分布:dbcached 和 NMDB 既可以安裝在同一台伺服器上,也可以安裝在不同的伺服器上,多台 dbcached 伺服器可以對應一台 NMDB 伺服器。
● 特長:dbcached 對於“讀”大於“寫”的應用尤其適用。
● 其他:《dbcached 的容錯移轉支援、設計方向以及與 Memcachedb 的不同之處》

 

 

 

列存系列

 

Hadoop之Hbase

 

耶魯大學之HadoopDB

GreenPlumFaceBook之Cassandra

Cassandra: API: many Thrift » languages, Protocol: ?, Query Method: MapReduce, Replicaton: , Written in: Java, Concurrency: eventually consistent , Misc: like "Big-Table on Amazon Dynamo alike",  initiated by Facebook, Slides » , Clients »

Cassandra是facebook開源出來的一個版本,可以認為是BigTable的一個開源版本,目前twitter和digg.com在使用。

Cassandra特點

  • 靈活的schema,不需要象資料庫一樣預先設計schema,增加或者刪除欄位非常方便(on the fly)。
  • 支援range查詢:可以對Key進行範圍查詢。
  • 高可用,可擴充:單點故障不影響叢集服務,可線性擴充。

Cassandra的主要特點就是它不是一個資料庫,而是由一堆資料庫節點共同構成的一個分布式網路服務,對Cassandra的一個寫操作,會 被複製到其他節點上去,對Cassandra的讀操作,也會被路由到某個節點上面去讀取。對於一個Cassandra群集來說,擴充性能是比較簡單的事 情,只管在群集裡面添加節點就可以了。我看到有文章說Facebook的Cassandra群集有超過100台伺服器構成的資料庫群集。

Cassandra也支援比較豐富的資料結構和功能強大的查詢語言,和MongoDB比較類似,查詢功能比MongoDB稍弱一些,twitter的平台架構部門領導Evan Weaver寫了一篇文章介紹Cassandra:http://blog.evanweaver.com/articles/2009/07/06/up-and-running-with-cassandra/,有非常詳細的介紹。

Cassandra以單個節點來衡量,其節點的並發讀寫效能不是特別好,有文章說評測下來Cassandra每秒大約不到1萬次讀寫請求,我也看 到一些對這個問題進行質疑的評論,但是評價Cassandra單個節點的效能是沒有意義的,真實的分散式資料庫訪問系統必然是n多個節點構成的系統,其並 發效能取決於整個系統的節點數量,路由效率,而不僅僅是單節點的並發負載能力。
Keyspace

Cassandra中的最大組織單元,裡麵包含了一系列Column family,Keyspace一般是應用程式的名稱。你可以把它理解為Oracle裡面的一個schema,包含了一系列的對象。
Column family(CF)

CF是某個特定Key的資料集合,每個CF物理上被存放在單獨的檔案中。從概念上看,CF有點象資料庫中的Table.
Key

資料必須通過Key來訪問,Cassandra允許範圍查詢,例如:start => '10050', :finish => '10070'
Column

在Cassandra中欄位是最小的資料單元,column和value構成一個對,比如:name:“jacky”,column是name,value是jacky,每個column:value後都有一個時間戳記:timestamp。

和資料庫不同的是,Cassandra的一行中可以有任意多個column,而且每行的column可以是不同的。從資料庫設計的角度,你可以理解 為表上有兩個欄位,第一個是Key,第二個是長文本類型,用來存放很多的column。這也是為什麼說Cassandra具備非常靈活schema的原 因。
Super column

Super column是一種特殊的column,裡面可以存放任意多個普通的column。而且一個CF中同樣可以有任意多個Super column,一個CF只能定義使用Column或者Super column,不能混用。下面是Super column的一個例子,homeAddress這個Super column有三個欄位:分別是street,city和zip: homeAddress: {street: "binjiang road",city: "hangzhou",zip: "310052",}

Sorting

不同於資料庫可以通過Order by定義定序,Cassandra取出的資料順序是總是一定的,資料儲存時已經按照定義的規則存放,所以取出來的順序已經確定了,這是一個巨大的效能優勢。有意思的是,Cassandra按照column name而不是column value來進行排序,它 定義了以下幾種選項:BytesType, UTF8Type, LexicalUUIDType, TimeUUIDType, AsciiType, 和LongType,用來定義如何按照column name來排序。實際上,就是把column name識別成為不同的類型,以此來達到靈活排序的目的。UTF8Type是把column name轉換為UTF8編碼來進行排序,LongType轉換成為64位long型,TimeUUIDType是按照基於時間的UUID來排序。例如:

Column name按照LongType排序:
{name: 3, value: "jacky"},
{name: 123, value: "hellodba"},
{name: 976, value: "Cassandra"},
{name: 832416, value: "bigtable"}

Column name按照UTF8Type排序:
{name: 123, value: "hellodba"},
{name: 3, value: "jacky"},
{name: 832416, value: "bigtable"}
{name: 976, value: "Cassandra"}

下面我們看twitter的Schema:
<Keyspace Name="Twitter">
<ColumnFamily CompareWith="UTF8Type" Name="Statuses" />
<ColumnFamily CompareWith="UTF8Type" Name="StatusAudits" />
<ColumnFamily CompareWith="UTF8Type" Name="StatusRelationships"
CompareSubcolumnsWith="TimeUUIDType" ColumnType="Super" />
<ColumnFamily CompareWith="UTF8Type" Name="Users" />
<ColumnFamily CompareWith="UTF8Type" Name="UserRelationships"
CompareSubcolumnsWith="TimeUUIDType" ColumnType="Super" />
</Keyspace>

我們看到一個叫Twitter的keyspace,包含若干個CF,其中StatusRelationships和 UserRelationships被定義為包含Super column的CF,CompareWith定義了column的定序,CompareSubcolumnsWith定義了subcolumn的排序 規則,這裡使用了兩種:TimeUUIDType和UTF8Type。我們沒有看到任何有關column的定義,這意味著column是可以靈活變更的。

為了方便大家理解,我會嘗試著用關係型資料庫的建模方法去描述Twitter的Schema,但千萬不要誤認為這就是Cassandra的資料模型,對於Cassandra來說,每一行的colunn都可以是任意的,而不是象資料庫一樣需要在建表時就建立好。

Users CF記錄使用者的資訊,Statuses CF記錄tweets的內容,StatusRelationships CF記錄使用者看到的tweets,UserRelationships CF記錄使用者看到的followers。我們注意到排序方式是TimeUUIDType,這個類型是按照時間進行排序的UUID欄位,column name是用UUID函數產生(這個函數返回了一個UUID,這個UUID反映了當前的時間,可以根據這個UUID來排序,有點類似於timestamp 一樣),所以得到結果是按照時間來排序的。使用過twitter的人都知道,你總是可以看到自己最新的tweets或者最新的friends.

儲存

Cassandra是基於列儲存的(Bigtable也是一樣),這個和基於列的資料庫是一個道理。

我對Cassandra資料模型的理解:

1.column name存放真正的值,而value是空。因為Cassandra是按照column name排序,而且是按列儲存的,所以往往利用column name存放真正的值,而value部分則是空。例如:“jacky”:“null”,“fenng”:”null”

2.Super column可以看作是一個索引,有點象關係型資料庫中的外鍵,利用super column可以實現快速定位,因為它可以返回一堆column,而且是排好序的。

3.排序在定義時就確定了,取出的資料肯定是按照確定的順序排列的,這是一個巨大的效能優勢。

4. 非常靈活的schema,column可以靈活定義。實際上,colume name在很多情況下,就是value(是不是有點繞)。

5.每個column後面的timestamp,我並沒有找到明確的說明,我猜測可能是資料多版本,或者是底層清理資料時需要的資訊。

最後說說架構,我認為架構的核心就是有所取捨,不管是CAP還是BASE,講的都是這個原則。架構之美在於沒有任何一種架構可以完美的解決各種問題,資料庫和NoSQL都有其應用情境,我們要做的就是為自己找到合適的架構。

 

 

 

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.