cassandra数据备份_Cassandra中的数据建模
cassandra數據備份
在關系數據模型中,我們為域中的每個對象建模關系/表。 對于Cassandra,情況并非如此。本文將詳細介紹在Cassandra中進行數據建模時需要考慮的所有方面。 以下是Cassandra數據建模的粗略概述。
從上圖可以看出, 概念數據建模和應用程序查詢是構建模型時要考慮的輸入。 對于任何建模(無論是關系數據庫還是Cassandra),概念數據建模都是相同的,因為它更多地是關于獲取有關實體,關系及其屬性(因此稱為ER模型)所需的系統功能的知識。
考慮以下有關病理實驗室門戶的示例。 通過此病理實驗室門戶,實驗室可以向同意進行建議的所有測試的門戶進行注冊。 此外,它還允許患者(用戶)在門戶網站上注冊,以通過他/她選擇的實驗室來預定測試約會。 這是概念模型的相關部分,將在Cassandra中進行數據建模:
Cassandra中的數據建模是查詢驅動的。 因此,下一步是確定需要支持的應用程序級查詢。 對于所舉的示例,這是我們感興趣的查詢列表:
- 問題1:通過指定的注冊號獲取實驗室詳細信息?
- 問題2:按預訂順序獲取給定實驗室要處理的所有待處理訂單?
- 問題3:通過用戶的電子郵件ID /電話號碼查看用戶的詳細信息?
- 問題4:獲取指定時間段內用戶的所有掛單?
映射規則:列出應用程序查詢后,將應用以下規則將概念模型轉換為邏輯模型。
- 規則1:列出我們將在其上執行基于相等性查詢的屬性。 例如:按注冊編號查找實驗室。
- 規則2:列出在上一步中列出的查詢中必須使用的基于范圍的屬性。
- 規則3:應用程序感興趣的結果是否有排序? 例如:返回用戶按其姓名升/降序排序?
從概念模型和查詢中,我們可以看到僅在第一季度使用了實體“實驗室”。 由于Q1基于等式,因此只能從映射規則中應用規則1。 因此,“實驗室”表可以設計如下:
create table lab_detail(registration_number text, name text, address text, primary key(registration_number));
實體“用戶”已在第三季度使用。 該查詢指定通過電子郵件ID或電話號碼獲取用戶詳細信息。 在關系數據庫中,我們可以使用電子郵件ID /電話號碼之一作為標識符創建單個用戶表。 如果表中的數據很大,則可以在非標識符列上創建索引以加快數據檢索速度。 但是在Cassandra中,這是以不同的方式建模的。 我們可以使用2個表來解決此問題:
create table users_by_email(email text primary key, phone_number text, first_name text, last_name text, address text);
create table users_by_phone(phone_number text primary key, email text, first_name text, last_name text, address text);
當我們要基于不屬于主鍵的列查詢表時,可以使用二級索引 。 但是在表上創建二級索引時必須小心。 不建議在許多情況下使用它們:
如我們所見,二級索引并不適合我們的用戶表,最好創建一個滿足應用程序目的的其他表。 請注意, 數據復制在Cassandra數據建模中非常普遍。 但是由于性能原因,我們應該限制要復制多少數據。 現在,創建不同表的問題在于,需要注意可能的數據一致性異常。
- 如果更新在一個表中成功而在另一個表中失敗怎么辦?
- 如何在兩個表中保持數據一致,以便在兩個表中查詢用戶數據都能獲得相同的結果?
盡管Cassandra不支持參照完整性,但是有一些方法可以解決這些問題- 批次和輕量交易 (LWT) 。 注意,與關系數據庫一樣,Cassandra中的批處理未用于提高性能。 此處的批處理用于實現操作的原子性,而異步查詢用于提高性能。 批處理操作的不正確使用可能會由于協調器節點上的更大壓力而導致性能下降。 更多關于此這里 。 當有必要在寫入之前執行讀取時,LWT可用于實現數據完整性(要寫入的數據取決于已讀取的數據)。 但是,據說LWT查詢比常規查詢慢許多倍。 使用LWT時,需要特別小心,因為它們的伸縮性不好。
實現此目的的另一種方法是使用實例化視圖 。 它們解決了應用程序維護多個表以同步方式引用相同數據的問題。 為了保持數據與基本表一致,Cassandra代替了應用程序維護這些表,而是負責更新視圖。 結果,為了保持這種一致性,寫操作將受到很小的性能損失。 但是一旦創建了物化視圖,我們就可以像對待其他任何表一樣對待它。 既然我們已經了解了視圖,那么我們可以重新考慮先前的users_by_phone設計:
create table users_by_email(email text primary key, phone_number text, first_name text, last_name text, address text);
create materialized view users_by_phone as
select * from users_by_email where phone_number is not null and email is not
null and primary key(phone_number, email);
注意,“不為空”約束必須應用于主鍵中的每一列。 因此,到目前為止,我們已經在應用程序工作流程中解決了Q1和Q3。 現在剩下第二和第四季度了:
- 問題2:按預訂順序獲取給定實驗室要處理的所有待處理訂單?
- 問題4:獲取指定期間內用戶的所有掛單?
在一種情況下,必須由用戶獲取訂單詳細信息,而在另一種情況下,必須由實驗室獲取訂單詳細信息。 在關系數據庫中,我們會將訂單,用戶和實驗室建模為不同的關系。 使用讀取數據的JOIN查詢可以在這些關系上實現Q2和Q4。 由于無法進行讀取級別連接,因此必須在Cassandra中以不同的方式進行建模。 必須完成數據非規范化才能實現此用例。 作為非規范化的一部分,數據將被復制。 但是,如前所述,Cassandra的經驗法則之一是不要將數據復制視為一件壞事。 與時間相比,我們基本上會在空間上進行權衡。 由于以下原因, Cassandra寧愿在寫時聯接而不是在讀時聯接。
- 可以通過向群集添加更多節點來擴大數據復制的規模,而聯接則無法處理大量數據。
- 同樣,數據復制允許具有恒定的查詢時間,而分布式聯接對協調器節點施加了巨大壓力。 因此,它建議寫時連接而不是讀時連接。 由于實驗室和用戶總共是兩個不同的實體,因此可以使用兩個不同的表對這些查詢進行建模。
Cassandra的一般建議是盡可能避免客戶端加入。 因此,我們使用邏輯模型中的表(orders_for_user)和視圖(orders_for_lab)從概念模型中對“訂單”實體進行建模,就像之前所做的那樣。 創建支持Q4的表時,必須考慮映射規則#1(基于平等的屬性:user_id)和#2(基于范圍的屬性:booking_time)。 將列order_id和test_id作為主鍵的一部分添加,以支持該行的唯一性。
create table orders_for_user(user_id text, order_id text, lab_id text, test_id text, booking_time timestamp, amount_paid double, primary key(user_id, booking_time, order_id, test_id));
類似地,可以考慮映射規則#1(基于平等的屬性:lab_id)和#3(屬性的聚類順序:booking_time)對視圖進行建模
create materialized view orders_for_lab as
select * from orders_for_user where lab_id is not null and order_id is not
null and test_id is not null and user_id is not null primary key(lab_id,
booking_time, test_id, order_id, user_id) with clustering order by(booking_time asc, order_id asc, test_id asc, user_id asc);
最后要考慮的一點是,建模數據時不要讓分區大小變得太大。 可以將新字段添加到分區鍵以解決此不平衡問題。 例如:如果某些實驗室獲得的訂單數量比其他實驗室多,那么這會通過將更多的負載分配給集群中的少數幾個節點而在分區中造成不平衡。 為了解決這個問題,我們可以添加一個bucket-id列,將每個實驗室1000個訂單分組到一個分區中。 通過這種方式,負載在群集的所有節點之間平均分配。
翻譯自: https://www.javacodegeeks.com/2019/05/data-modeling-cassandra.html
cassandra數據備份
總結
以上是生活随笔為你收集整理的cassandra数据备份_Cassandra中的数据建模的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 11999元起!华为Mate60 RS
- 下一篇: sql 注射_只能在测试中注射吗?