Skip to content
This repository was archived by the owner on Mar 9, 2019. It is now read-only.

Performance degradation ~18-32GB (long running large DB, unreachable unfreed, delete) #688

@chuckg

Description

@chuckg

We're experiencing large write performance degradation over time as a result of sustained IO/throughput happening in BoltDB. But first, a little about our use case:

  • We're writing a sequential log of data, wherein the majority of our keys are 64 byte integers that primarily increase. One bucket serves to hold a variable payload size (change stream from Postgres).
  • We clean up old log data that has passed some expiration. In all the stats below, we're using a 48 hour retention period and clean up hourly. Deletes are done in batches of 1000 using manual transaction management.

We currently have 3 buckets:

  • Fix Linux build. #1 Bucket(64 byte variable key) -> Bucket(64 byte integer key, ascending insertion order generally) -> N bytes (1KB-128KB; think database change log of old row/new row)
  • gofmt #2 Bucket(64 byte integer key, ascending insertion order generally) -> 64 byte (max) random value
  • Spill to dirty pages, write to disk #3 Bucket(64 byte integer key, ascending insertion order generally) -> 64 byte integer value

All use 50% (default) fill.

After running the server for 4-5 days, we ended up with a 32GB database that has pegged the i3.xl we're running it on at ~3-4K IOPS with ~375-400 MB/s throughput. These levels of IO are sustained once they begin; as expected, restarting the server has no effect. During that time, we would have run the log cleaner around 48 times (once per hour). The cleaner removes data by age in the following way:

Here's a profile of the time it took to complete the clean up batches with their duration and the number of rows removed (from the default bucket):
screen shot 2017-05-23 at 1 26 31 pm

I ran the bolt tool against the database at 32GB:

Then we compacted the database, which took it to ~17GB:

bash-4.3# bolt compact -o compact.db pglx.db
33956966400 -> 17677443072 bytes (gain=1.92x)
bash-4.3# du -hs *
17G    compact.db
32G    pglx.db

Booting the server against the 17GB database, the IOPS/throughput returned to normal for around 12 hours. At that point, everything returned to the same level degradation as the 32GB database:

Finally, here's cpu/alloc from pprof on the ~18GB server while it was pegging the IO:

The culprit appears to be runtime.memmove and runtime.memclr, which I'm guessing it spending most of it's time reshuffling our data. Any thoughts on how to address the issue?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions