Package: emcache
A high performance asynchronous Python client forMemcachedwith full batteries includedEmcache stands on the giant’s shoulders and implements most of the characteristics that are desired for a Memcached client based
on the experience of other Memcached clients, providing the following main characteristics:Support for many Memcached hosts, distributing traffic around them by using theRendezvous hashingalgorithm.Support for different commands and different flag behaviors likenoreply,exptimeorflags.Support for SSL/TLS protocol.Support forautodiscovery, which should work with AWS and GCP memcached clusters.Adaptativeconnection pool, which increases the number of connections per Memcache host depending on the traffic.Node healthinesstraceability and an optional flag for disabling unhealthy for participating in the commands.Metrics foroperations and connections, send them to your favourite TS database for knowing how the Emcache driver is behaving.Listen to the most significantcluster events, for example for knowing when a node has been marked as unhealthy.Speed, Emcache is fast. See the benchmark section.UsageFor installingpipinstallemcacheThe following snippet shows the minimal stuff that would be needed for creating a new client and saving a new key and retrieving later the value.importasyncioimportemcacheasyncdefmain():client=awaitemcache.create_client([emcache.MemcachedHostAddress('localhost',11211)])awaitclient.set(b'key',b'value')item=awaitclient.get(b'key')print(item.value)awaitclient.close()asyncio.run(main())Emcache has currently support, among many of them, for the following commands:getUsed for retrieving a specific key.getsCas version that returns also the case token of a specific key.get_manyMany keys get version.gets_manyMany keys + case token gets version.setSet a new key and valueaddAdd a new key and value, if and only if it does not exist.replaceUpdate a value of a key, if an only if the key does exist.appendAppend a value to the current one for a specific key, if and only if the key does exist.prependPrepend a value to the current one for a specific key, if and only if the key does exist.casUpdate a value for a key if and only if token as provided matches with the ones stored in the Memcached server.Take a look at the documentation for getting a list of all of theoperationsthat are currently supported.Some of the commands have support for the following behavior flags:noreplyfor storage commands likesetwe do not wait for an explicit response from the Memcached server. Sacrifice the explicit ack from the Memcached server for speed.flagsfor storage we can save an int16 value that can be retrieved later on by fetch commands.exptimefor storage commands this provides a way of configuring an expiration time, once that time is reached keys will be automatically evicted by the Memcached serverFor more information about usage,read the docs.BenchmarksThe following table shows how fast - operations per second - Emcache can be compared to the other two Memcached Python clients,aiomcacheandpymemcache.
For that specific benchmark two nodes were used, one for the client and one for the Memcached server, using 32 TCP connections
and using 32 concurrent Asyncio tasks - threads for the use case of Pymemcache. For Emcache and Aiomcacheuvloopwas used as a default loop.In the first part of the benchmark, the client tried to run as muchasetoperations it could, and in a second step the same was
done but usinggetoperations.ClientConcurrencySets opS/secSets latency AVGGets opS/secGets latency AVGaiomcache32338720.00094341830.00093pymemcache32327920.00097329610.00096emcache32494100.00064492120.00064emcache (autobatching)32494100.00064890520.00035Emcache performed better than the other two implementations reaching almost 50K ops/sec for get and set operations. One autobatching is used
it can boost the throughtput x2 (more info about autobatching below)Another benchmark was performed for comparing how each implementation will behave in case of having to deal with more than 1 node, a new
benchmark was performed with different cluster sizes but using the same methodology as the previous test by first, performing as many set
operations it could and later as many get operations it could. For this specific use test with Aiomemcahce could not be used since it
does not support multiple nodes.ClientConcurrencyMemcahed NodesSets opS/secSets latency AVGGets opS/secGets latency AVGpymemcache322212600.00150215830.00148emcache322422450.00075480790.00066pymemcache324153340.00208154580.00207emcache324397860.00080476030.00067pymemcache32899030.0032399700.00322emcache328421670.00075464720.00068The addition of new nodes did not add almost degradation for Emcache, in the last test with 8 nodes Emcache reached 42K
get ops/sec and 46K set ops/sec. On the other hand, Pymemcached suffered substantial degradation making Emcache ~x5 times.
faster.AutobatchingAutobatching provides you a way for fetching multiple keys using a single command, batching happens transparently behind the scenes
without bothering the caller.For start using the autobatching feature you must provide the parameterautobatchingas True, hereby all usages of thegetandgetscommand will send batched requests behind the scenes.Get´s are piled up until the next loop iteration. Once the next loop iteration is reached all get´s are transmitted using the
same Memcached operation.Autobatching can boost up the throughput of your application x2/x3.DevelopmentClone the repository and its murmur3 submodulegitclone--recursivegit@github.com:emcache/emcacheCompile murmur3pushdvendor/murmur3makestaticpopdInstall emcache with dev dependenciesmakeinstall-dev