-
-
Notifications
You must be signed in to change notification settings - Fork 651
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Feature] scaling, read-only replicas on a shared database #622
Comments
Hi, thank you for your proposal. My comments:
|
hi @martinboehm , thanks for response. so
We use Blockbook on Amazon with GP3 drives, 6000 IOPS, 300MBps and on "fast endpoints" it can provide 500-1700 RPS, depending on the CPU, per instance. This performance is fine for us. However, if you use ethereum and call I think I also noticed github issues (2) saying OOM-killed Blockbook during synchronization damages the database and reindexing is needed. Cannot this be the same reason (kill when adding new blocks)? Can Blockbook be terminated with Is this relevant?
Database of
We aimed to fix it by adding read-only readers that cannot in principle damage the shared database even if OOM kills them anytime. Fixing it in the code is out of our scope.
As mentioned, GP3 SSD with 6000 IOPS and 300MBps is enough for our needs. We are also using storage-optimized instances with NVMe SSD storage (native latency, 6-8x better than GP3, 0.09-0.1m rand read lat, 13.8k read IO, 10.2 write IO; sync uses just 6100 IOPS) for fast synchronization. Both usecases work great.
My experience is a bit different. I implemented Blockbook benchmark with Locust, having 16 workers issuing thousands of requests per second each, from multiple servers. I tested several endpoints with random addresses and transactions collected from the blockchain sampling. There is a huge gap in endpoint performance, We rate-limit the requests, according to data collected from the benchmark. Some native rate-limiting in the Blockbook would be also great. For instance, setting maximum page size in config file, so DoSer cannot use 1000 records per page, with all transaction details for the busiest addresses on the chain (I sampled blocks and picked those addresses that are quite busy, collected thousands of those). Or allowing only a subset of
Thanks again for your time |
Btw @martinboehm if you setup a testing instance of Blockbook for Ethereum mainnet (or you already have one that can be tested), I can benchmark it from Amazon with my tools. We can check if we can replicate the problem with DB corruption by overloading the server with generic requests. What do you think? We could maybe also publish result of this benchmark, could be handy for others. |
tldr: Idea is to deploy and scale Blockbook instances in cloud. Store synced DB on a single storage (e.g.,Amazon EFS), one master, multiple read-only replicas.
According to our benchmarking measurements, we could benefit from hooking a single storage (fully synchronized database) to multiple read-only worker nodes as CPU/RAM requirements increase with number of requests (assuming FS is fast enough).
Naive scaling solution would be to start new Blockbook instances from a "template" instance, that is kept running and fully synchronized. The problem is that copying Blockbook to a new machine requires quite some amount of bandwidth and time to copy full database (e.g., Ethereum 2.3 TB). First copy pass can be done when source instance is running. Second copy pass (e.g., with
rsync
) only changed files are copied, saving the bandwidth and time. However, during the second pass, source instance has to be stopped to ensure database consistency. Then both nodes have to resync. Thus the Blockbook instance cloning is slow and requires downtime.We also noticed that Blockbook could nicely scale horizontally according to the demand (pay only for consumed resources), keeping the database storage separated (again billed by IOPS, consumed storage).
Also, if a read-only replica gets overloaded, it cannot crash the database / make it inconsistent. Otherwise, without proper rate limiting it is quite easy to DoS the Blockbook with few requests, leading to unrecoverable database (you have to basically reindex or recover from snapshot).
Seems like RocksDB already support few interesting features that could make this possible:
So the question is whether it is already supported or whether you consider adding support for easier scaling with read-only replicas. If Blockbook could be configured to open the database as secondary, from a shared storage (NFS / Amazon EFS), responding only to user-issued requests, it would work, I guess.
The benefit is easier horizontal scaling, better availability and increased robustness. As there would be only a single syncing master (lets say master won't respond to user requests), chances of a DB corruption to an overload are minimal.
Another scaling approach could be adding a new FS-level abstraction layer so many remote workers could use the same synced database over a controlled API. But it seems like a lot of work compared to sharing DB on a file level with locks (Amazon EFS is fully posix compatible, there can be another storage backend, Ceph, ...)
Does it make sense to have a read-only replicas or is there another scaling approach I am missing?
Thanks for info and opinion!
The text was updated successfully, but these errors were encountered: