> Also new seq_types can be added and old seq_types can be deleted. This means I often need to ALTER TABLE to add and drop columns.
Kai, unless I'm misunderstanding something, I don't see why you need to alter the table to add a new seq type. From a data model perspective, these are just new values in a row. If you do have columns which are specific to particular seq_types, data modeling does become a little more challenging. In that case you may get some advantage from using collections (especially map) to store data which applies to only a few seq types. Or defining a schema which includes the set of all possible columns (that's when you're getting into ALTERs when a new column comes or goes). > All sequences with the same seq_id tend to grow at the same rate. Note that it is an anti pattern in Cassandra to append to the same row indefinitely. I think you understand this because of your original question. But please note that a sub partitioning strategy which reuses subpartitions will result in degraded read performance after a while. You'll need to rotate sub partitions by something that doesn't repeat in order to keep the data for a given partition key grouped into just a few sstables. A typical pattern there is to use some kind of time bucket (hour, day, week, etc., depending on your write volume). I do note that your original question was about preserving data locality - and having a consistent locality for a given seq_id - for best offline analytics. If you wanted to work for this, you can certainly also include a blob value in your partitioning key, whose value is calculated to force a ring collision with this record's sibling data. With Cassandra's default partitioner of murmur3, that's probably pretty challenging - murmur3 isn't designed to be cryptographically strong (it doesn't work to make it difficult to force a collision), but it's meant to have good distribution (it may still be computationally expensive to force a collision - I'm not that familiar with its internal workings). In this case, ByteOrderedPartitioner would be a lot easier to force a ring collision on, but then you need to work on a good ring balancing strategy to distribute your data evenly over the ring. On Sun Dec 07 2014 at 2:56:26 AM DuyHai Doan <doanduy...@gmail.com> wrote: > "Those sequences are not fixed. All sequences with the same seq_id tend > to grow at the same rate. If it's one partition per seq_id, the size will > most likely exceed the threshold quickly" > > --> Then use bucketing to avoid too wide partitions > > "Also new seq_types can be added and old seq_types can be deleted. This > means I often need to ALTER TABLE to add and drop columns. I am not sure if > this is a good practice from operation point of view." > > --> I don't understand why altering table is necessary to add seq_types. > If "seq_types" is defined as your clustering column, you can have many of > them using the same table structure ... > > > > > > On Sat, Dec 6, 2014 at 10:09 PM, Kai Wang <dep...@gmail.com> wrote: > >> On Sat, Dec 6, 2014 at 11:18 AM, Eric Stevens <migh...@gmail.com> wrote: >> >>> It depends on the size of your data, but if your data is reasonably >>> small, there should be no trouble including thousands of records on the >>> same partition key. So a data model using PRIMARY KEY ((seq_id), seq_type) >>> ought to work fine. >>> >>> If the data size per partition exceeds some threshold that represents >>> the right tradeoff of increasing repair cost, gc pressure, threatening >>> unbalanced loads, and other issues that come with wide partitions, then you >>> can subpartition via some means in a manner consistent with your work load, >>> with something like PRIMARY KEY ((seq_id, subpartition), seq_type). >>> >>> For example, if seq_type can be processed for a given seq_id in any >>> order, and you need to be able to locate specific records for a known >>> seq_id/seq_type pair, you can compute subpartition is computed >>> deterministically. Or if you only ever need to read *all* values for a >>> given seq_id, and the processing order is not important, just randomly >>> generate a value for subpartition at write time, as long as you can know >>> all possible values for subpartition. >>> >>> If the values for the seq_types for a given seq_id must always be >>> processed in order based on seq_type, then your subpartition calculation >>> would need to reflect that and place adjacent seq_types in the same >>> partition. As a contrived example, say seq_type was an incrementing >>> integer, your subpartition could be seq_type / 100. >>> >>> On Fri Dec 05 2014 at 7:34:38 PM Kai Wang <dep...@gmail.com> wrote: >>> >>>> I have a data model question. I am trying to figure out how to model >>>> the data to achieve the best data locality for analytic purpose. Our >>>> application processes sequences. Each sequence has a unique key in the >>>> format of [seq_id]_[seq_type]. For any given seq_id, there are unlimited >>>> number of seq_types. The typical read is to load a subset of sequences with >>>> the same seq_id. Naturally I would like to have all the sequences with the >>>> same seq_id to co-locate on the same node(s). >>>> >>>> >>>> However I can't simply create one partition per seq_id and use seq_id >>>> as my partition key. That's because: >>>> >>>> >>>> 1. there could be thousands or even more seq_types for each seq_id. >>>> It's not feasible to include all the seq_types into one table. >>>> >>>> 2. each seq_id might have different sets of seq_types. >>>> >>>> 3. each application only needs to access a subset of seq_types for a >>>> seq_id. Based on CASSANDRA-5762, select partial row loads the whole row. I >>>> prefer only touching the data that's needed. >>>> >>>> >>>> As per above, I think I should use one partition per >>>> [seq_id]_[seq_type]. But how can I archive the data locality on seq_id? One >>>> possible approach is to override IPartitioner so that I just use part of >>>> the field (say 64 bytes) to get the token (for location) while still using >>>> the whole field as partition key (for look up). But before heading that >>>> direction, I would like to see if there are better options out there. Maybe >>>> any new or upcoming features in C* 3.0? >>>> >>>> >>>> Thanks. >>>> >>> >> Thanks, Eric. >> >> Those sequences are not fixed. All sequences with the same seq_id tend to >> grow at the same rate. If it's one partition per seq_id, the size will most >> likely exceed the threshold quickly. Also new seq_types can be added and >> old seq_types can be deleted. This means I often need to ALTER TABLE to add >> and drop columns. I am not sure if this is a good practice from operation >> point of view. >> >> I thought about your subpartition idea. If there are only a few >> applications and each one of them uses a subset of seq_types, I can easily >> create one table per application since I can compute the subpartition >> deterministically as you said. But in my case data scientists need to >> easily write new applications using any combination of seq_types of a >> seq_id. So I want the data model to be flexible enough to support >> applications using any different set of seq_types without creating new >> tables, duplicate all the data etc. >> >> -Kai >> >> >> >