frankenphp icon indicating copy to clipboard operation
frankenphp copied to clipboard

Idea: Memcached client in golang with request pipelining

Open TysonAndre opened this issue 3 years ago • 3 comments

For https://memcached.org/ servers or proxies

This may be out of scope.

Motivation

  • Memcached is heavily used in some web applications for caching state or the results of expensive operations (db queries, results of reading data from web services, etc)

  • If there are hundreds of workers, it'd reduce cpu and memory resource usage and syscalls if they shared a small finite number of memcache connections (pool)

    (unless there are ~32+ cpu cores, 1 connection may suffice)

  • Both golang and php could use the same client, allowing moving method implementations to/from golang (e.g. check a json array for a value, add a value)

    • (or read/write with serializers such as PECL msgpack, etc. https://msgpack.org/ has many implementations. )
    • Though this could go in its own PECL, the ability to share the same client is useful

Benchmarking notes

  • Request pipelining does better when there is actual network latency (https://github.com/twitter/twemproxy/#pipelining) (e.g. non-pipelined golang clients would be limited to 1000 requests per second with 0.001 second network latency)
  • https://github.com/twitter/twemproxy/ has performance issues when clients pipeline requests. Reduce mbuf size with -m $MBUF_SIZE if this is configured to connect to a twemproxy proxy
  • I haven't benchmarked this yet.

Background

It would be extremely useful to have compatibility with the memcached flags int used to indicate the chosen serializer https://github.com/php-memcached-dev/php-memcached/ (source of http://pecl.php.net/memcached )

  • Years ago, I implemented a pipelining memcached client, and embedded it in https://github.com/TysonAndre/golemproxy#about for a hackathon (it should work and has unit tests, but I never had time to try it)
  • I believe the pool config syntax in that codebase is compatible with https://github.com/twitter/twemproxy/#pipelining

The memcached client this uses is based on https://github.com/bradfitz/gomemcache

  • This rewrites parts of it and adds pipelining support to that library.

Alternatives

Use existing memcached or memcache PECL normally

TysonAndre avatar Oct 22 '22 14:10 TysonAndre

Most libraries have implementations for igbinary when it comes to caching (Symphony/Laravel), but I'm not sure about msgpack. IMHO, the implementation should consider the cached object as an opaque blob and not do any introspection since that is usually how you end up with quirks and weird bugs, even security issues, if it can be forced to crash in the right way.

withinboredom avatar Oct 23 '22 07:10 withinboredom

True, igbinary has much wider usage (I'm one of the leads of igbinary), and the igbinary string deduplication when serializing is useful for data with repeated strings https://github.com/igbinary/igbinary#implementation-details

https://pecl.php.net/package-stats.php?pid=895&rid=&cid=25 https://pecl.php.net/package-stats.php?pid=930&rid=&cid=29

IMHO, the implementation should consider the cached object as an opaque blob and not do any introspection since that is usually how you end up with quirks and weird bugs, even security issues, if it can be forced to crash in the right way.

Agreed, the implementation I had in mind would pass the data blob and flags to the C code, and the C code would call the unserializers (in a way similar to the way the memcached pecl calls the unserializer)

TysonAndre avatar Oct 23 '22 12:10 TysonAndre

Agreed, the implementation I had in mind would pass the data blob and flags to the C code, and the C code would call the unserializers (in a way similar to the way the memcached pecl calls the unserializer)

Ah, that makes sense I think.

withinboredom avatar Oct 23 '22 13:10 withinboredom