我认为自从 Cassandra 1.2 最近发布以来,这值得更新。
在过去的 18 个月里,我一直在生产中使用 Cassandra 来开发社交游戏。
我认为您必须使用 Cassandra 才能发挥其优势。因此,有必要很好地了解它的作用和作用,了解要使用哪种数据模型,甚至确定另一个数据库解决方案是否对您更有用。
OrderedPartitioner 仅在您的应用程序依赖键范围查询时才有用,但您为此放弃了 Cassandra 最强大的功能之一:自动分片和负载平衡。代替行键范围查询尝试使用同一行中的列名范围来实现您需要的相同功能。 TL;DR 使用它的节点之间不会平衡读/写。
RandomPartioner(md5 散列)和 MurmurPartitioner(Murmur 散列,更好更快)是支持大数据和高访问频率的必经之路.您唯一放弃的是键范围查询。同一行中的所有内容仍位于集群中的同一节点上,您可以在这些节点上使用比较器和列名范围查询。 TL;DR : 使用它来进行适当的平衡,你不会放弃任何重大的东西。
你应该知道的关于 cassandra 的事情:
Cassandra 最终是一致的。 Cassandra 选择用一致性换取高可用性和出色的分区 (http://en.wikipedia.org/wiki/CAP_theorem)。但是您可以从 cassandra 获得一致性,这完全取决于您在读取和写入时的一致性策略。在谈论使用 cassandra 时,这是一个非常重要且复杂的话题,但您可以在此处详细了解它 http://www.datastax.com/docs/1.2/dml/data_consistency。
根据经验(并为简单起见),我在 QUORUM ConsistencyLevel 读写(因为在我的应用程序中,读取的频率往往与写入的频率顺序相同)。如果您的应用程序的写入量很大并且读取发生的频率要低得多,那么请使用 write at ONE 并 read at ALL。或者,如果您的用例相反(写入频率远低于读取频率),那么您可以尝试在 ONE 上读取并在 ALL 上写入。
如果一致性是您要解决的问题,那么使用 ANY 作为写入的一致性级别并不是一个好主意,因为它保证了突变已经到达集群,但不能保证它已经被写入任何地方。这是我在 cassandra 上获得写入静默失败的唯一情况。
这些都是简单的规则,可以让您轻松开始 cassandra 开发。要从生产集群中获得尽可能高的一致性和性能,您应该认真研究这个主题并真正理解它。
如果您需要具有实体(表)之间复杂关系的人类可读数据模型,那么我认为 Cassandra 不适合您。 MySQL 和 NewSQL 可能对您的用例更有帮助。
要知道的一件好事是,cassandra 大致如何保存和读取数据。每当您写入时(删除实际上是在 cassandra 中写入“墓碑”值),系统会将新值及其时间戳放在新的物理位置。
当您阅读时,cassandra 会尝试提取某个 key/column_name 位置的所有写入数据,并返回他能找到的最新数据(具有最高时间戳的数据,由客户端提供)。因此,节点所需的内存直接取决于写入频率。 cassandra 中有一个压缩过程,负责清理旧的突变。 Cassandra 有一个内部缓存,在读取时会使用该位置的最新值进行更新。
SSTables(持久化数据的数据结构)在磁盘上的合并/压缩可以由读取引起,但最好不要指望它。清除墓碑和过期列(使用生存时间功能)是由垃圾收集器管理的不同机制(有关详细信息,请参阅 GC 宽限时间设置)。
这让我想到了最后一点:确保您的写入和读取在您的集群中保持平衡!
假设您的所有用户都需要非常频繁地更新一个位置。
不要仅将理论上的单个位置映射到一个行键!这将使您的所有写入仅落在集群中的一个节点上。如果它不能让一切都崩溃(因为你有摇滚明星管理员),它至少会严重削弱集群的性能。
我的建议是将您的写入存储在足够多的不同行键中,以便您将写入分布在集群中的所有节点上。要检索该单个理论位置的所有数据,请在所有“子行键”上使用 multi_get。
示例:
我想列出所有活动的 http 会话(已分配 uuid)。
不要将所有内容保存到一个“会话”行键中。我用作 6 个节点的 cassandra 集群的行键是:
_会话。
然后我有一个小的 16 键 multi_get 来检索所有活动会话,或者我仍然可以通过使用简单的 get 来判断会话是否处于活动状态(如果我当然知道它的 uuid)。
如果您的集群更大,您可能需要使用哈希函数来生成存储桶键。