Re^6: How to maintain a persistent connection over sockets? (Amazing! Multi-tasking without multi-tasking!)by flexvault (Monsignor)
|on May 05, 2012 at 08:14 UTC||Need Help??|
And it has to be. It is the cache server and the single point of all I/O for one environment or class of database(s). All independent processes call this for reading and writing to disk. If it's a write, then it updates the cache and adds to a queue to update the record on disk (child process). If it's a read, it checks the cache and if present it returns the cached copy or does the I/O to get the record if it exists.
Background: The Classic Problem!
Lots of locking has to be used to cache a database between processes. This is exactly where Berkeley Db fails without a separate ( user provided ) locking mechanism. Berkeley DB uses a 4KB root that is shared by all processes, and you have a built-in race condition.
So by forcing all cache activity into one process, and only that process locks/unlocks the cache and the related databases, you force an orderly environment. The cache server can have children that lock/unlock the tree that they are working on.
Now the cache is actually a HoH. For instance, you could have 30 databases in one environment with 400 users and each database and each user has a set of hashes. The user hashes are mostly maintained in the client ( calling ) processes. But the database hashes can grow large, so they have frequency activity as well and data buffers. My first implementation used arrays. But Perl's 'exists' and using hashes has given the performance I wanted and needed.
When I run benchmarks for the single-user version, the core is maxed out at 100%. When I benchmark the multi-user, the cores run at 8 to 10%, so I'm not utilizing the cache server as well as I could.
Just to give you the correct picture.
"Well done is better than well said." - Benjamin Franklin