Open dfwilbanks395 opened 11 months ago
see https://gerrit.readyset.name/c/readyset/+/1054 for background here
Do we track size only to make eviction decisions? Is there any another purpose of tracking materialized df state size? I am asking b/c there are alternative approaches which might work better especially when other components memory usage is taken into account (RocksDB): getting process RSS or using jemalloc stats (live allocations size)?
- Inconsistent use of
Domain::state_size.
I checked the code and found that this value is never read, there are store/decrements, no reads. What is the purpose of updating this value during eviction it it is never read?
it's read here:
On
KeyedState
andPartialMap
overheads. They are not only data structures which adds up toMemoryState
memory usage, there are others:IndexMap
, for example. Calculating these overheads for everyinsert/remove
operation is not feasible due to inner complexity of these data types- only as total overhead forMemoryState,
which can be done inMemoryState::deep_size_of()
. It's doable (not easy), but can result in some performance penalty (hard to estimate yet).
HashBag
value counter overhead. It's simple for a givenHashBag
, but to get totalHashBag
overheads forMemoryState
we need to iterate through all values (Rows
) kept in thisMemoryState
Not sure how fast or slow it can be. Again, we can not do increments/decrements on this overhead type during insert or remove.
Maybe instead of trying to get perfect memory accounting everywhere, we could look at what this overhead is (especially since I think it's either constant or bounded) and make the decision based on that. I don't think we need to be perfect, but I'm willing to be convinced otherwise.
Incorrectly double count duplicate rows in
MemoryState::insert().
I did not find this in the code, but I found other small issue, which I fixed.
what's the question here?
I think that if we call MemoryState::insert()
twice with the same value of r
each time, we will drop the second r
instead of storing it since Rows
is implemented with a HashBag
Why do we call it twice?
We call it on every insert, so we could make two identical calls if the user has inserted a duplicate value.
…so if you insert row twice you will get V = 2
Yup, I wasn't clear, but this is where I think we end up double counting duplicates. We account for the memory of the Row
on every insert. However, if we're inserting a duplicate row to the HashBag
, we drop the Row
and just increment the counter.
The information is already propagated - the mem_size
field is updated on MemoryState
and read via the deep_size_of
function in Domain
Reopening this issue to investigate why system benchmarks time outs with memory limit set.
We track the size of materialized dataflow state to apply heuristics for evictions.
Some small issues regarding memory tracking
base_row_size_from_comparison()
does not track Range comparisonsbase_row_size
takes the size of aRow::default()
instead ofRows::default()
HashBag
, though this is pretty insignificant.MemoryState::insert()
but do not double count when removingSingleState
s, though this is also pretty insignificantbytes_freed
rather thanbytes_freed + key_bytes
fromMemoryState::evict_keys()
KeyedState
andPartialMap
, though we might not want to try to account for thisself.state_size
inDomain::handle_exiction()
. Among other issues, evicting from a reader does not always causeself.state_size
to be updated.