Closed dlmarion closed 2 months ago
Reduced the calls to ZooCache in #4685, but was not able to remove all of them. Repopulating ZooCache with lots of tables is expensive, doing it in quick succession will progressively slow down. We might need a different code path, something like TableOperations.createTables
, to create many tables vs creating a single table.
I am not super familiar with the code for caching but it looks like the entire cache is invalidated on changes.
Would it be possible to user an observer and just have Zookeeper send notifications when the node changes for the table name/id? The cache could get updates for table creation and deletions.
Would it be possible to user an observer and just have Zookeeper send notifications when the node changes for the table name/id? The cache could get updates for table creation and deletions.
Discussed this with @cshannon offline. Suspect writing would need custom ZK code to keep the cache up to date. The goal is to have a Map<TableName, TableId>
however in ZK we have Map<TableId, TableName>
. With enough custome observers may be able to keep the Map<TableName, TableId>
up to date based on changes in ZK.
An alternative approach may be to create Map<TableName, TableId>
in zookeeper as an index conceptually. This would make the accumulo client code super simple as it could use zoocache for the Map<TableName, TableId>
stored in zookeeper. The only problem is this index in ZK needs to be kept consistent. The consistency may not be a problem though because all table operations like create, import, clone, rename, and delete that would need to update this Map<TableName, TableId>
index in zk already run as fate operations. So the updates to this index could easily be done via fate. If the code added to fate is simple then a lot of complex client code could be removed and it may result in a net simplification of the code base, not sure though. This would probably not be a change for 2.1.x initially.
Looking into how the fate operations work currently they call Utils.getTableNameLock().lock()
to ensure only a single fate operation does anything with table names. If we ever allow fate operations to run on multiple processes, then this would not work very well as this lock assumes only one process runs fate operations at a time. If Map<TableName, TableId>
exist in zookeeper, then we could possibly remove the need for Utils.getTableNameLock().lock()
and use the ability to have atomic operations on the Map<TableName, TableId>
in zookeeper to ensure that two tables are not created with the same name concurrently. So there may be an additional benefit to having Map<TableName, TableId>
in zookeeper.
If we ever allow fate operations to run on multiple processes, then this would not work very well as this lock assumes only one process runs fate operations at a time.
If the table path in ZooKeeper included the namespace, then you could just lock the namespace when creating, cloning, renaming, or importing a table to ensure table names are unique. This would also reduce your search space in ZooKeeper.
https://github.com/apache/accumulo/pull/4685 is merged and I think is a sufficient improvement for the 2.1.3 patch release. I'm going to close this, unless there are any objections.
I opened an issue about creating an index in zookeeper for mapping table names to table ids. That seems to have multiple benefits and was something discussed related to this issue, but no need to keep this issue open for that.
thanks for the quick turn-around!
User reported this issue in the user mailing list. I wrote a small test (below) which shows that table creation gets progressively slower.
When I jstacked the Manager I noticed the following thread stack:
It looks like ServerAmpleImpl is trying to update the metadata table for the new current table, but the code has to go back to ZooKeeper to update ZooCache for the tableIdMap due to the prior table creation.