[HN Gopher] Drop-In Replacement for Memcached
       ___________________________________________________________________
        
       Drop-In Replacement for Memcached
        
       Author : mfrw
       Score  : 61 points
       Date   : 2021-12-12 19:09 UTC (3 hours ago)
        
 (HTM) web link (www.memc.rs)
 (TXT) w3m dump (www.memc.rs)
        
       | awestroke wrote:
       | This seems to be a concurrent hashmap (dashmap[1]) with a server
       | speaking the memcached protocol. I know both memcached and redis
       | use sophisticated strategies to reduce allocation calls and
       | memory fragmentation, but this seems to do nothing like that.
       | 
       | [1]: https://docs.rs/dashmap/latest/dashmap/
        
         | rurban wrote:
         | Memcache uses an outdated and slow hash and hashtable. This is
         | using jemalloc and a concurrent hashtable. Seems to be miles
         | better.
        
           | Lhiw wrote:
           | Not this again...
           | 
           | https://news.ycombinator.com/item?id=28833202
        
       | lumost wrote:
       | Biggest value prop seems to be that it's a single binary built
       | off cargo, and that it's rust based. I wouldn't be surprised to
       | see "single binary" become a selling point for container based
       | shops even if all else is equal.
        
         | galkk wrote:
         | Soon we'll see entire docker compose stack packed into single
         | binary and everything will go back again
        
       | nkuttler wrote:
       | Hm, would be nice if they had a comparison. More than just "it's
       | Rust".
        
         | [deleted]
        
       | nvr219 wrote:
       | RIP LiveJournal
        
       | montroser wrote:
       | Cool, but what problem is this meant to solve? How does it
       | compare to memcached in terms of performance?
        
         | StreamBright wrote:
         | The not yet rewritten in Rust problem.
        
         | mfrw wrote:
         | I am not among the ones who would blindly say 'rewrite it in
         | rust', but given what happened with log4j, I would much rather
         | choose a safe implementation given the memory safety provided
         | by rust.
         | 
         | This also does not mean rust might not have its fair share of
         | bugs; IMHO the probability is a little less.
         | 
         | Edit: I mentioned the log4j RCE as it was new & do not mean to
         | imply that it would not have happened if we had a rust
         | implementation. As the comments have mentioned, it would be the
         | same in any language IMO
        
           | zamalek wrote:
           | > IMHO the probability is a little less.
           | 
           | Exactly, Rust simply eliminates a certain class of bugs. You
           | can still make some really major mistakes in the absence of
           | these bugs, e.g. "goto fail" could have easily been written
           | in Rust.
        
             | ordiel wrote:
             | Most certainly opening the door to a diffetent kind of
             | bugs. This mentally of tying bugs to a language
             | demonstrates a very poor understanding of the issues
             | themselves, and if anything a large impacting bug
             | demonstrates wide adoption of an individual piece, most
             | probably choosen due to its stability or ease of use.
             | 
             | Remember heartbleed?...
        
               | staticassertion wrote:
               | > Most certainly opening the door to a diffetent kind of
               | bugs.
               | 
               | No? There's no law of conservation of bug class or
               | something, you can eliminate bug classes without
               | introducing a new one.
               | 
               | > This mentally of tying bugs to a language demonstrates
               | a very poor understanding of the issues themselves,
               | 
               | No it doesn't.
               | 
               | > and if anything a large impacting bug demonstrates wide
               | adoption of an individual piece, most probably choosen
               | due to its stability or ease of use.
               | 
               | I don't think this has held true historically, and log4j
               | is a good example of this (though there are many others).
               | 
               | > Remember heartbleed?...
               | 
               | A weird point to bring up since heartbleed was an out of
               | bounds memory read.
        
             | vlmutolo wrote:
             | The "goto fail" bug isn't a great example; Rust actually
             | _does_ specifically guard against this by requiring curly
             | braces around the body of  "if".
             | 
             | Here's an explanation of "goto fail", which includes a code
             | snippet.
             | 
             | https://nakedsecurity.sophos.com/2014/02/24/anatomy-of-a-
             | got...
             | 
             | If C conditionals required explicit braces around the body,
             | the second fail would have been redundant code instead of a
             | security vulnerability.
             | 
             | Additonally, Rust will warn you if you have "unreachable"
             | code, such as all the code after the unconditional "goto
             | fail". Though, I'm sure modern C compilers would also warn
             | about this.
             | 
             | All that said, Rust definitely does have plenty of bug
             | classes left for people to trip over. Integer
             | under/overflows come to mind (though they're just logic
             | errors instead of undefined behavior).
        
               | tialaramex wrote:
               | In the same class as the integer over/underflows, Rust
               | also doesn't warn for throwing away information when
               | casting. So (my_value as u16) _might_ be a completely
               | safe transformation from an unsigned one byte my_value to
               | a u16, but it _might_ be throwing away the top 16-bits of
               | a 32-bit value and Rust doesn 't think that's worth any
               | additional caution.
               | 
               | Rust also hasn't boarded the "People can't remember
               | precedence rules" train like some modern languages. It
               | has fewer operators with unnecessary values, reducing
               | some opportunities for mistakes like C's increment
               | footgun, but it does still have precedence and so you can
               | still forget the precedence rules which the compiler is
               | going to apply to your code.
               | 
               | But there are a _lot_ of things Rust does catch, and
               | there are even more things that aren 't caught by Rust
               | the language per se but are caught in idiomatic Rust
               | because the language affords better ways to do things.
               | Locking is an example, idiomatic Rust locking means you
               | can't make the lock A but change B mistake seen so often
               | in real bugs, because idiomatic use of Rust's type system
               | would put the variable B _inside_ the lock for B, if you
               | didn 't take the lock you don't have the variable to
               | change it. https://doc.rust-
               | lang.org/std/sync/struct.Mutex.html
        
           | sorokod wrote:
           | You misunderstand the recent RCE in log4j. It has nothing to
           | do with memory safety and can be implemented in Rust without
           | any difficulty.
        
             | spullara wrote:
             | Further it wasn't even a bug. It was the well defined
             | behavior working as specified.
        
             | staticassertion wrote:
             | > and can be implemented in Rust without any difficulty.
             | 
             | Not really. You'd have to fight the language and pull in
             | some crates, to be sure. There's no native object
             | serialization in rust and it's not really a concept in the
             | language or ecosystem - except perhaps in the future with
             | wasm runtimes.
             | 
             | There are numerous details of log4j that, in general, just
             | don't apply to rust code.
             | 
             | edit: Since perhaps people don't believe me...
             | 
             | Rust has no equivalent of JNDI, pickle, etc. There is no
             | way to send rust 'code' except, perhaps, wasm. Certainly
             | there's no _well supported_ way with decades of history of
             | being ingrained into libraries, or patterns that support
             | it.
        
             | mfrw wrote:
             | I did not mean that the RCE of log4j is a memory safety
             | issue, its just that, I would prefer to choose something
             | where the probability of me having to wake up at the middle
             | of the night and fix is less. Honestly, I would care less
             | if it were memory safety or whatever, given I had to wake
             | up at midnight :)
        
               | johnisgood wrote:
               | Just because it is written in Rust, it does not mean that
               | you will have less bugs or whatever to fix. I could
               | easily say that if it is written in Ada or Nim, then you
               | will have way less bugs, as those languages are way
               | easier to understand, and they are safe & fast & easy.
               | Nim is just as easy as Python, and it is safe if you want
               | it to.
        
               | mfrw wrote:
               | I completely agree. My choice of words was not not right.
        
               | moonchrome wrote:
               | >it does not mean that you will have less bugs or
               | whatever to fix
               | 
               | But it does since you eliminate an entire class of bugs,
               | and a class that's generally the source of most exploits
               | out there (eg. heartbleed comes to mind as a similar
               | level of exploit but was a result of memory errors).
               | 
               | JVM does the same with GC, and so do a lot of other
               | languages, but when it comes to rewriting non-managed
               | code Rust is a great choice over C in my book, I would
               | feel better about introducing a Rust dependency over a
               | C/C++ dependency just based on that.
               | 
               | As for ADA and Nim, if it's some black box docker service
               | then sure, otherwise if I have to include it in my build
               | pipeline that's a hard pass.
        
               | johnisgood wrote:
               | > But it does since you eliminate an entire class of bugs
               | 
               | As opposed to what language? C? x86 assembly? You may be
               | right, but I was using Ada and Nim as an example, not C.
               | I could have used D as well.
        
             | tialaramex wrote:
             | I think it would actually be pretty tricky to do that in
             | Rust without realising what you'd done, as seemingly
             | happened to log4j.
             | 
             | The root of the log4j problem is a failure to distinguish
             | between log format strings and the formatted log string,
             | beyond that what happens is that Java allows a lot of
             | flexibility at runtime which simply doesn't exist in Rust.
             | In Java it's fine to, at _runtime_ pull in classes you 've
             | never used before and run them, you can't do that in Rust -
             | the types only existed at compile time. Indeed this is a
             | key _feature_ of Rust, because it means wrapper types are
             | free at runtime, invaluable to the embedded firmware
             | community who love type checking and other safety features
             | but can 't afford runtime overhead.
        
       | aftbit wrote:
       | What can this do that memcached can't? We use memcached heavily
       | in PROD but I would be hard pressed to replace it with an upstart
       | competitor just because its is possible.
        
         | buro9 wrote:
         | Memcache is a BSD licence.
         | 
         | This is AGPL or commercial.
         | 
         | The biggest difference I could find was not in the capability
         | of it as a drop-in replacement but in the change of licence as
         | any changes you might have to fit your needs now has different
         | terms.
         | 
         | I guess the bet here is predicated on that... are companies
         | running versions of memcached that are much improved and
         | they're not sharing those improvements? Could this be a way to
         | make those improvements public by this replacing memcached over
         | time?
         | 
         | I'm not sure how they could do a commercial licence once
         | they've accepted contributions, if they don't have a CLA
         | granting the right over the contributions. But IANAL, etc.
        
           | CodeWriter23 wrote:
           | > Could this be a way to make those improvements public by
           | this replacing memcached over time?
           | 
           | Those who wish to share their contributions will, regardless
           | of license. Those who do not, will stick to code with BSD-
           | style licenses.
        
           | erk__ wrote:
           | They do indeed have a CLA: https://cla-assistant.io/memc-
           | rs/memc-rs
        
       | welder wrote:
       | Stop using RAM for caching, SSDs are just as fast now with
       | LevelDB/RocksDB and can store a magnitude more data. Look into
       | SSDB [1] instead of Memcached.
       | 
       | I know it's Redis, but it's basically the same as Memcached if
       | you only use the key-value set/get commands.
       | 
       | See this blog post [2] and this Gophercon 2021 talk [3] for
       | examples of it's use in production.
       | 
       | [1] https://github.com/ideawu/ssdb
       | 
       | [2] https://wakatime.com/blog/45-using-a-diskbased-redis-
       | clone-t...
       | 
       | [3] https://www.youtube.com/watch?v=35eIxI_n5ZM&t=10533s
        
         | jeffbee wrote:
         | I mean, hard no on both claims. A memory cache (even memcached,
         | which might not be state of the art) stomps all over the
         | performance claims of SSDB. Memcached can do ~250kqps on one
         | core, roughly depending of exactly what kind of cores are in
         | question, and can typically turn around a request in < 50us.
         | SSDB is only "just as fast" if the rest of your stack is so
         | insensitive to performance that you can't measure an order of
         | magnitude difference in service latency.
        
           | scrubs wrote:
           | agree - most sstables use memory looking on disk if needed.
           | ssds do not have the bandwidth or low latency RAM has apart
           | from the additional I/O path to get it onto or out of disk.
           | Now, not to say memory+ssd can't rock ... but ssd!=DDRAM.
        
         | ec109685 wrote:
         | SSDB is faster even if data size is >> ram size?
         | 
         | Otherwise, you're going to be adding equivalent memory to get
         | to equivalent performance between memcached and ssdb.
        
         | aseipp wrote:
         | There are no latency numbers to be seen anywhere unless I
         | missed them. If the difference in latency between RAM/disk
         | isn't noticeable in these workloads because you have enough
         | slack in the system, the distinction doesn't really matter, you
         | can use whatever (case in point, the linked article uses cost-
         | of-egress as the sole motivation, it doesn't even mention
         | latency or QPS at all.)
         | 
         | Memcached also has a mechanism for storing _values_ (but not
         | keys) on disk for larger-than-memory datasets which works well
         | on big parallel flash drives.
         | 
         | EDIT: The website seems down but I was able to find a graph on
         | archive.org via
         | https://web.archive.org/web/20210721201604/https://ssdb.io/ but
         | without latency, only QPS in some simple benchmarks. It's not
         | slow, but if you're pushing high QPS-per-core or low latency,
         | there's no indication it will serve as well as alternatives,
         | and that can have a bigger impact on ROI than just the cost of
         | disk-vs-memory for your servers.
        
       ___________________________________________________________________
       (page generated 2021-12-12 23:00 UTC)