Wednesday, 8 January 2020

5个选择Apache Cassandra 而非DynamoDB的原因

概述

Apache Cassandra 以及DynamoDB 都是非常流行的分布式存储技术,这2个产品都在很多应用以及生产环境中得到了成功的使用。
在Instaclustr(一个公司),我们强烈依赖Apache Cassandra以及Apache Kafka.我们的客户群里非常的广泛,他们的体量以及公司的成熟度遍及各个层次,许多客户在选择Cassandra还是DynamoDB前已经做过了很重要的评估练习,还有一些客户已经将自己的应用从DynamoDB迁移到Cassandra之上了。
这篇博客提取了我们的客户选择Apache Cassandra的5个主要原因。

原因1:写入DynamoDB的成本巨大

对于许多实用的case来说,实用Apache Cassandra的成本比DynamoDB节省很多,这些主要是一些对于一些业务偏写入的客户来说.(在你的AWS的账单上可以显示的很清楚的是)写入成本是读取成本的5倍.对于Apache Cassandra来说写入比读取的成本低(主要是在你对使用的资源消耗上可以反映)。
注意:这点主要是AWS的自费模式以及Cassandra的原理决定上述情况。

原因2:移植性

我们知道DynamoDB只是存在于AWS平台,别的地方没有提供的,对于多租户的sass平台产品,只提供一个单独的实列来说,那么全部放在AWS平台来说并不是什么大问题;然而很多客户基于很多原因希望能够有一个客户自己定制的安装以及管理的环境(一般是一些大客户)。选择Cassandra允许你的程序在任何Linux的平台上面运行。

原因3:架构设计无需关心计价模型

DynamoDB的计价方式是很复杂的,她有2套计价模型以及很多计价维度,使用了错误的计价模型或者你们的架构在设计的时候没有考虑产品计价可能会导致成本有数量级的差异。从另一个角度看,对程序来说可能是一个无关紧要的修改可能会造成极大的成本消耗;而使用cassandra的话你的可以控制自己的基础设施以及管理你自己费用开销,一旦你测试完成并确定了你的架构设计,你的开销基本上就是确定了的。

原因4:多Region的功能

Cassandra是第一个提供多region的多活nosql系统,虽然DynamoDB 提供了global table的功能,但是和cassandra对比的话还是有一些关键限制.多数限制中最重要的可能就是对于一个已有的global table你并不能添加副本(replicas),所以如果你设置好了2个region然后决定添加一个新的region你需要从一个空的表中进行重建.但是对于cassandra来说,你需要添加一个region是很平常的操作,且是完全的online操作.另一个比较重要的限制是对于global table的话,dynamodb只提供最终一致性,但是cassandra的可调一致性可以在多region中提供强一致(whereas Apache Cassandra’s tunable consistency levels can enforce strong consistency across multiple regions.).

原因5:避免 Vendor Lock-In

Cassandra是完全的开源软件,由Apache 基金会决定他的管理和开发,她的开发以及管理主要是基于社区利益的,可以在任何的云平台以及内部平台运行。DynamoDB 是AWS的一款解决方案她将你锁定在DynamoDB而且将你的应用锁定在AWS的生态体系之中。
虽然这是人们选择cassandra的主要原因但是也有很多在功能上差异原因而选择cassandra比如:
  • DynamoDB的容量受partition限制,每个分区最大的是1千的写容量以及3千的读容量。Cassandra的容量分布在每个节点上面,每个节点通常提供一个高于此数量级的分区限制;
  • Cassandra的CQL提供了一个类似sql的且对于开发者来说容易学习使用的方式;
  • DynamoDB 只允许单值分区以及排序,但是cassandra允许多值排序,这是一个较小的区别,但是cassandra这样可以降低应用复杂性;
  • Cassandra提供了聚合函数,在某些case下是很有效的;

from : https://yq.aliyun.com/articles/719047

MongoDB Schema 設計指南 (Part II) - 反正規化的威力

MongoDB 反正規化的威力

上一次介紹的「MongoDB Schema 設計指南」之後,今天來介紹一下續集趴兔 (原文在此)。在上一篇文章中,已經介紹了一些基本的設計技巧,我們可以透過以下兩個問題幫助我們分析選用適合的 Schema Model。
  1. 在我們的參照實體中,需要 stand-alone (資料獨立性) 這樣的特性嗎?
  2. 對於參照實體的基數多寡,可以選定使用 one-to-few, one-to-many 或 one-to-squillions 哪一種模式?
如果上述的問題您還沒有非常清楚,那麼建議可以複習一下前一篇文章的介紹。接下來我們要介紹一些進階的 MongoDB Schema 設計方法,介紹利用 Two-Way Referencing (雙向參照) 與 Denormalization (反正規化) 這些技巧來使用 MongoDB,讓我們的查詢更有效率。

Two-Way Referencing (雙向參照設計)

Two-Way Referencing 我也不知道怎麼翻譯,所以先暫時叫做「雙向參照」吧!先回顧一下之前提到的 one-to-squillions (海量級關聯模式),可以快速在海量級母體中查詢資料。但是在兩個關聯實體中,有時候查詢的圍度與面向不同,有時候由 A 查 B,有時候由 B 查 A。這時候我們就需要雙向參照的設計模式,舉個工作單管理的例子如下:
上面儲存每個使用的的資料與目前擁有的工作單 (Tasks),然而每個工作單的集合如下:
上述工作單 Document 其中有個 owner 欄位,並且指向所屬的擁有者。這時無碖我們想要查詢某個人的工作單,或者由某個工作單查到所屬的使用者,都可以很方便地完成,人員 (person) 與工作單 (tasks) 皆保持資料一致性 (Stand-Alone)。那缺點呢?缺點就是一旦有資料關係需要變更,兩個物件內容都要進行更新,必須手動來同步關聯狀態。

Intermediate (媒介設計模式)

多對一反正規化 (Denormalizing from Many -> One)

這個方法應該是到目前為止,用到「反正規化」概念最深入的模式,主要將一對多模型進行反正規化,減少查詢的 Join 作動以提升效率。先舉個例子說明一下,比如一個「商品」可能由數個「組件」組成,是一個多對多的關係,如下:
若是我們想要很快地撈出「商品」與他所屬的「組件」名稱,在上述原本已經正規化的狀態下,就必須再去查詢 parts collection 才能獲得「組件名稱」。為了更有效率地進行查詢,可以透過反正規化來完成,我們將資料的儲存方式改成下面的範例:
上述我們直接在 parts 欄位放上我們常需要的 name 欄位,如此一來只要 Query 一個 Collection 就可以獲得我們想要的資訊,減少 Join 的執行,這樣的方式對於大量資料的查詢是很有幫助的。如此違反正規化的過程就稱為「反正規化」,缺點可以很清楚地發現,因為 name 被重複儲存記錄,維護的時候就很麻煩。反正規劃之後,若是要維持資料一致性,修改 name 欄位就必須更新所有地方。像是上述這樣的例子並不會很常更改「組件」實體的 name 欄位,整體獲得的效率是高過維護成本。
此外,如果要查詢每個組件的其他詳細資料,當然要用到 Join,在 MongoDB 裡面我們稱為 Application-level Join,可以再次撈取另一個 Collection 進行組合,如下:

一對多反正規化 (Denormalizing from One -> Many)

這個例子前面介紹的概念其實差不多,在上述的案例,假設我們想快速查詢「組件」資訊,又想要查詢這些「組件」所屬的「商品」名稱,如果想要加速查訊效率,不想要使用 Application Join,那就是對「商品」的名稱欄位進行反正規化。修改後的 Schema 如下:
上述例子將「商品」的 name 欄位重複設定在「組件」中的 product_name 欄位中,反正規化之後就可以大幅提升查詢效率。當然失去資料的一致性,在維護上要付出的代價是相同的,根據實際使用的情境進行反正規化,在 MongoDB 或其他分散式資料庫都是常見的手法。在進行反正規化之前,我們必須理解以下兩個重要的特性:
  • 反正規劃之後,就會失去資料的一致性 (Stand-Alone)
  • 在讀取頻率高,寫入頻率低的情況下,進行反正規化才有意義
系統需求經過分析之後,將更新頻率不高的欄位進行反正規劃,會是不錯的選擇。在 Query 的便利性與效率會大大提昇,是不是很有趣呢?今天就先介紹到這,下次再見囉。YY

from : https://blog.toright.com/posts/4537/mongodb-schema-%E8%A8%AD%E8%A8%88%E6%8C%87%E5%8D%97-part-ii-%E5%8F%8D%E6%AD%A3%E8%A6%8F%E5%8C%96%E7%9A%84%E5%A8%81%E5%8A%9B.html