Those are two different cases though. It *sounds like* (again, I may be missing the point) you're trying to overwrite a value with another value. You're either going to serialize a blob and overwrite a single cell, or you're going to overwrite all the cells and include a tombstone.
When you do a read, reading a single tombstone vs a single vs is essentially the same thing, performance wise. In your description you said "~ 20-100 events", and you're overwriting the event each time, so I don't know how you go to 10K tombstones either. Compaction will bring multiple tombstones together for a cell in the same way it compacts multiple values for a single cell. I sounds to make like you're taking some advice about tombstones out of context and trying to apply the advice to a different problem. Again, I might be misunderstanding what you're doing. On Fri, Jan 4, 2019 at 10:49 AM Tomas Bartalos <tomas.barta...@gmail.com> wrote: > Hello Jon, > > I thought having tombstones is much higher overhead than just overwriting > values. The compaction overhead can be l similar, but I think the read > performance is much worse. > > Tombstones accumulate and hang for 10 days (by default) before they are > eligible for compaction. > > Also we have tombstone warning and error thresholds. If cassandra scans > more than 10 000 tombstones, she will abort the query. > > According to this article: > https://opencredo.com/blogs/cassandra-tombstones-common-issues/ > > "The cassandra.yaml comments explain in perfectly: *“When executing a > scan, within or across a partition, we need to keep the tombstones seen in > memory so we can return them to the coordinator, which will use them to > make sure other replicas also know about the deleted rows. With workloads > that generate a lot of tombstones, this can cause performance problems and > even exhaust the server heap. "* > > Regards, > Tomas > > On Fri, 4 Jan 2019, 7:06 pm Jonathan Haddad <j...@jonhaddad.com wrote: > >> If you're overwriting values, it really doesn't matter much if it's a >> tombstone or any other value, they still need to be compacted and have the >> same overhead at read time. >> >> Tombstones are problematic when you try to use Cassandra as a queue (or >> something like a queue) and you need to scan over thousands of tombstones >> in order to get to the real data. You're simply overwriting a row and >> trying to avoid a single tombstone. >> >> Maybe I'm missing something here. Why do you think overwriting a single >> cell with a tombstone is any worse than overwriting a single cell with a >> value? >> >> Jon >> >> >> On Fri, Jan 4, 2019 at 9:57 AM Tomas Bartalos <tomas.barta...@gmail.com> >> wrote: >> >>> Hello, >>> >>> I beleive your approach is the same as using spark with " >>> spark.cassandra.output.ignoreNulls=true" >>> This will not cover the situation when a value have to be overwriten >>> with null. >>> >>> I found one possible solution - change the schema to keep only primary >>> key fields and move all other fields to frozen UDT. >>> create table (year, month, day, id, frozen<Event>, primary key((year, >>> month, day), id) ) >>> In this way anything that is null inside event doesn't create tombstone, >>> since event is serialized to BLOB. >>> The penalty is in need of deserializing the whole Event when selecting >>> only few columns. >>> Can anyone confirm if this is good solution performance wise? >>> >>> Thank you, >>> >>> On Fri, 4 Jan 2019, 2:20 pm DuyHai Doan <doanduy...@gmail.com wrote: >>> >>>> "The problem is I can't know the combination of set/unset values" --> >>>> Just for this requirement, Achilles has a working solution for many years >>>> using INSERT_NOT_NULL_FIELDS strategy: >>>> >>>> https://github.com/doanduyhai/Achilles/wiki/Insert-Strategy >>>> >>>> Or you can use the Update API that by design only perform update on not >>>> null fields: >>>> https://github.com/doanduyhai/Achilles/wiki/Quick-Reference#updating-all-non-null-fields-for-an-entity >>>> >>>> >>>> Behind the scene, for each new combination of INSERT INTO table(x,y,z) >>>> statement, Achilles will check its prepared statement cache and if the >>>> statement does not exist yet, create a new prepared statement and put it >>>> into the cache for later re-use for you >>>> >>>> Disclaiment: I'm the creator of Achilles >>>> >>>> >>>> >>>> On Thu, Dec 27, 2018 at 10:21 PM Tomas Bartalos < >>>> tomas.barta...@gmail.com> wrote: >>>> >>>>> Hello, >>>>> >>>>> The problem is I can't know the combination of set/unset values. From >>>>> my perspective every value should be set. The event from Kafka represents >>>>> the complete state of the happening at certain point in time. In my table >>>>> I >>>>> want to store the latest event so the most recent state of the happening >>>>> (in this table I don't care about the history). Actually I used wrong >>>>> expression since its just the opposite of "incremental update", every >>>>> event >>>>> carries all data (state) for specific point of time. >>>>> >>>>> The event is represented with nested json structure. Top level >>>>> elements of the json are table fields with type like text, boolean, >>>>> timestamp, list and the nested elements are UDT fields. >>>>> >>>>> Simplified example: >>>>> There is a new purchase for the happening, event: >>>>> {total_amount: 50, items : [A, B, C, new_item], purchase_time : >>>>> '2018-12-27 13:30', specials: null, customer : {... }, fare_amount,...} >>>>> I don't know what actually happened for this event, maybe there is a >>>>> new item purchased, maybe some customer info have been changed, maybe the >>>>> specials have been revoked and I have to reset them. I just need to store >>>>> the state as it artived from Kafka, there might already be an event for >>>>> this happening saved before, or maybe this is the first one. >>>>> >>>>> BR, >>>>> Tomas >>>>> >>>>> >>>>> On Thu, 27 Dec 2018, 9:36 pm Eric Stevens <migh...@gmail.com wrote: >>>>> >>>>>> Depending on the use case, creating separate prepared statements for >>>>>> each combination of set / unset values in large INSERT/UPDATE statements >>>>>> may be prohibitive. >>>>>> >>>>>> Instead, you can look into driver level support for UNSET values. >>>>>> Requires Cassandra 2.2 or later IIRC. >>>>>> >>>>>> See: >>>>>> Java Driver: >>>>>> https://docs.datastax.com/en/developer/java-driver/3.0/manual/statements/prepared/#parameters-and-binding >>>>>> Python Driver: >>>>>> https://www.datastax.com/dev/blog/python-driver-2-6-0-rc1-with-cassandra-2-2-features#distinguishing_between_null_and_unset_values >>>>>> Node Driver: >>>>>> https://docs.datastax.com/en/developer/nodejs-driver/3.5/features/datatypes/nulls/#unset >>>>>> >>>>>> On Thu, Dec 27, 2018 at 3:21 PM Durity, Sean R < >>>>>> sean_r_dur...@homedepot.com> wrote: >>>>>> >>>>>>> You say the events are incremental updates. I am interpreting this >>>>>>> to mean only some columns are updated. Others should keep their original >>>>>>> values. >>>>>>> >>>>>>> You are correct that inserting null creates a tombstone. >>>>>>> >>>>>>> Can you only insert the columns that actually have new values? Just >>>>>>> skip the columns with no information. (Make the insert generator a bit >>>>>>> smarter.) >>>>>>> >>>>>>> Create table happening (id text primary key, event text, a text, b >>>>>>> text, c text); >>>>>>> Insert into table happening (id, event, a, b, c) values >>>>>>> ("MainEvent","The most complete info we have right now","Priceless","10 >>>>>>> pm","Grand Ballroom"); >>>>>>> -- b changes >>>>>>> Insert into happening (id, b) values ("MainEvent","9:30 pm"); >>>>>>> >>>>>>> >>>>>>> Sean Durity >>>>>>> >>>>>>> >>>>>>> -----Original Message----- >>>>>>> From: Tomas Bartalos <tomas.barta...@gmail.com> >>>>>>> Sent: Thursday, December 27, 2018 9:27 AM >>>>>>> To: user@cassandra.apache.org >>>>>>> Subject: [EXTERNAL] Howto avoid tombstones when inserting NULL values >>>>>>> >>>>>>> Hello, >>>>>>> >>>>>>> I’d start with describing my use case and how I’d like to use >>>>>>> Cassandra to solve my storage needs. >>>>>>> We're processing a stream of events for various happenings. Every >>>>>>> event have a unique happening_id. >>>>>>> One happening may have many events, usually ~ 20-100 events. I’d >>>>>>> like to store only the latest event for the same happening (Event is an >>>>>>> incremental update and it contains all up-to date data about happening). >>>>>>> Technically the events are streamed from Kafka, processed with Spark >>>>>>> an saved to Cassandra. >>>>>>> In Cassandra we use upserts (insert with same primary key). So far >>>>>>> so good, however there comes the tombstone... >>>>>>> >>>>>>> When I’m inserting field with NULL value, Cassandra creates >>>>>>> tombstone for this field. As I understood this is due to space >>>>>>> efficiency, >>>>>>> Cassandra doesn’t have to remember there is a NULL value, she just >>>>>>> deletes >>>>>>> the respective column and a delete creates a ... tombstone. >>>>>>> I was hoping there could be an option to tell Cassandra not to be so >>>>>>> space effective and store “unset" info without generating tombstones. >>>>>>> Something similar to inserting empty strings instead of null values: >>>>>>> >>>>>>> CREATE TABLE happening (id text PRIMARY KEY, event text); insert >>>>>>> into happening (‘1’, ‘event1’); — tombstone is generated insert into >>>>>>> happening (‘1’, null); — tombstone is not generated insert into >>>>>>> happening >>>>>>> (‘1’, '’); >>>>>>> >>>>>>> Possible solutions: >>>>>>> 1. Disable tombstones with gc_grace_seconds = 0 or set to reasonable >>>>>>> low value (1 hour ?) . Not good, since phantom data may re-appear 2. >>>>>>> ignore >>>>>>> NULLs on spark side with “spark.cassandra.output.ignoreNulls=true”. Not >>>>>>> good since this will never overwrite previously inserted event field >>>>>>> with >>>>>>> “empty” one. >>>>>>> 3. On inserts with spark, find all NULL values and replace them with >>>>>>> “empty” equivalent (empty string for text, 0 for integer). Very >>>>>>> inefficient >>>>>>> and problematic to find “empty” equivalent for some data types. >>>>>>> >>>>>>> Until tombstones appeared Cassandra was the right fit for our use >>>>>>> case, however now I’m not sure if we’re heading the right direction. >>>>>>> Could you please give me some advice how to solve this problem ? >>>>>>> >>>>>>> Thank you, >>>>>>> Tomas >>>>>>> --------------------------------------------------------------------- >>>>>>> To unsubscribe, e-mail: user-unsubscr...@cassandra.apache.org >>>>>>> For additional commands, e-mail: user-h...@cassandra.apache.org >>>>>>> >>>>>>> >>>>>>> ________________________________ >>>>>>> >>>>>>> The information in this Internet Email is confidential and may be >>>>>>> legally privileged. It is intended solely for the addressee. Access to >>>>>>> this >>>>>>> Email by anyone else is unauthorized. If you are not the intended >>>>>>> recipient, any disclosure, copying, distribution or any action taken or >>>>>>> omitted to be taken in reliance on it, is prohibited and may be >>>>>>> unlawful. >>>>>>> When addressed to our clients any opinions or advice contained in this >>>>>>> Email are subject to the terms and conditions expressed in any >>>>>>> applicable >>>>>>> governing The Home Depot terms of business or client engagement letter. >>>>>>> The >>>>>>> Home Depot disclaims all responsibility and liability for the accuracy >>>>>>> and >>>>>>> content of this attachment and for any damages or losses arising from >>>>>>> any >>>>>>> inaccuracies, errors, viruses, e.g., worms, trojan horses, etc., or >>>>>>> other >>>>>>> items of a destructive nature, which may be contained in this attachment >>>>>>> and shall not be liable for direct, indirect, consequential or special >>>>>>> damages in connection with this e-mail message or its attachment. >>>>>>> >>>>>>> --------------------------------------------------------------------- >>>>>>> To unsubscribe, e-mail: user-unsubscr...@cassandra.apache.org >>>>>>> For additional commands, e-mail: user-h...@cassandra.apache.org >>>>>>> >>>>>> >> >> -- >> Jon Haddad >> http://www.rustyrazorblade.com >> twitter: rustyrazorblade >> > -- Jon Haddad http://www.rustyrazorblade.com twitter: rustyrazorblade