40
Bullet Cache Balancing speed and usability in a cache server Ivan Voras <[email protected]>

Bullet Cache - FreeBSDivoras/slides/BSDCan2012-BulletCache.pdf · Introducing the Bullet Cache 1.Offers a smarter data structure to the user side than a simple key-value pair 2.Implements

  • Upload
    others

  • View
    0

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Bullet Cache - FreeBSDivoras/slides/BSDCan2012-BulletCache.pdf · Introducing the Bullet Cache 1.Offers a smarter data structure to the user side than a simple key-value pair 2.Implements

Bullet Cache

Balancing speed and usabilityin a cache server

Ivan Voras <[email protected]>

Page 2: Bullet Cache - FreeBSDivoras/slides/BSDCan2012-BulletCache.pdf · Introducing the Bullet Cache 1.Offers a smarter data structure to the user side than a simple key-value pair 2.Implements

What is it?

● People know what memcached is... mostly● Example use case:

– So you have a web page which is just dynamic enough so you can't cache it completely as an HTML dump

– You have a SQL query on this page whichis 99.99% always the same (same query, same answer)

– ...so you cache it

Page 3: Bullet Cache - FreeBSDivoras/slides/BSDCan2012-BulletCache.pdf · Introducing the Bullet Cache 1.Offers a smarter data structure to the user side than a simple key-value pair 2.Implements

Why a cache server?

● Sharing between processes– … on different servers

● In environments which do not implement application persistency

– CGI, FastCGI– PHP

● Or you're simply lazy and want something which works...

Page 4: Bullet Cache - FreeBSDivoras/slides/BSDCan2012-BulletCache.pdf · Introducing the Bullet Cache 1.Offers a smarter data structure to the user side than a simple key-value pair 2.Implements

A little bit of history...

● This started as my “pet project”...– It's so ancient, when I first started working

on it, Memcached was still single-threaded– It's gone through at least one rewrite and

a whole change of concept

● I made it because of the frustration I felt while working with Memcached

– Key-value databases are so very basic– “I could do better than that” :)

Page 5: Bullet Cache - FreeBSDivoras/slides/BSDCan2012-BulletCache.pdf · Introducing the Bullet Cache 1.Offers a smarter data structure to the user side than a simple key-value pair 2.Implements

Now...

● Used in production in my university's project

● Probably the fastest memory cache engine available (in specific circumstances)

● Available in FreeBSD ports (databases/mdcached)

● Has a 20-page User Manual :)

Page 6: Bullet Cache - FreeBSDivoras/slides/BSDCan2012-BulletCache.pdf · Introducing the Bullet Cache 1.Offers a smarter data structure to the user side than a simple key-value pair 2.Implements

What's wrong with memcached?

● Nothing much – it's solid work● The classic problem:

cache expiry / invalidation– memcached accepts a list of records to

expire (inefficient, need to maintain this list)

● It's fast – but is it fast enough?– Does it really make use of multiple CPUs

as efficiently as possible?

Page 7: Bullet Cache - FreeBSDivoras/slides/BSDCan2012-BulletCache.pdf · Introducing the Bullet Cache 1.Offers a smarter data structure to the user side than a simple key-value pair 2.Implements

Introducing the Bullet Cache

1. Offers a smarter data structure to the user side than a simplekey-value pair

2. Implements “interesting” internal data structures

3. Some interesting bells & whistles

Page 8: Bullet Cache - FreeBSDivoras/slides/BSDCan2012-BulletCache.pdf · Introducing the Bullet Cache 1.Offers a smarter data structure to the user side than a simple key-value pair 2.Implements

User-visible structure

● Traditional (memcached) style:– Key-value pairs– Relatively short keys (255 bytes)– ASCII-only keys (?)– (ASCII-only protocol)– Multi-record operations only with a list of

records– Simple atomic operations (relatively

inefficient - atoi())

Page 9: Bullet Cache - FreeBSDivoras/slides/BSDCan2012-BulletCache.pdf · Introducing the Bullet Cache 1.Offers a smarter data structure to the user side than a simple key-value pair 2.Implements

Introducing record tags

● They are metadata● Constraints:

– Must be fast (they are NOT db indexes)– Must allow certain types of bulk operations

● The implementation:– Both key and value are signed integers– No limit on the number of tags per record– Bulk queries: (tkey X) && (tval1, [tval2...])

Page 10: Bullet Cache - FreeBSDivoras/slides/BSDCan2012-BulletCache.pdf · Introducing the Bullet Cache 1.Offers a smarter data structure to the user side than a simple key-value pair 2.Implements

Record tags

● I heard you like key-value records so I've put key-value records into your key-value records...

record key record value

k v k v k v ...

generic metadata

Page 11: Bullet Cache - FreeBSDivoras/slides/BSDCan2012-BulletCache.pdf · Introducing the Bullet Cache 1.Offers a smarter data structure to the user side than a simple key-value pair 2.Implements

Metadata queries (1)

● Use case example: a web application has a page “/contacts” which contains data from several SQL queries as well as other sources (LDAP)

– Tag all cached records with(tkey,tval) = (42, hash(“/contacts”))

– When constructing page, issue query:get_by_tag_values(42, hash(“/contacts”))

– When expiring all data, issue query:del_by_tag_values(42, hash(“/contacts”))

Page 12: Bullet Cache - FreeBSDivoras/slides/BSDCan2012-BulletCache.pdf · Introducing the Bullet Cache 1.Offers a smarter data structure to the user side than a simple key-value pair 2.Implements

Metadata queries (2)

● Use case example: Application objects are stored (serialized, marshalled) into the cache, and there's a need to invalidate (expire) all objects of a certain type

– Tag records with(tkey, tval) = (object_type, instance_id)

– Expire withdel_by_tag_values(object_type, instance_id)

– Also possible: tagging object interdependance

Page 13: Bullet Cache - FreeBSDivoras/slides/BSDCan2012-BulletCache.pdf · Introducing the Bullet Cache 1.Offers a smarter data structure to the user side than a simple key-value pair 2.Implements

Under the hood

● It's “interesting”...● Started as a C project, now mostly

converted to C++ for easier modularization

– Still uses C-style structures and algorithms for the core parts – i.e. not std::containers

● Contains tests and benchmarks within the main code base

– C and PHP client libraries

Page 14: Bullet Cache - FreeBSDivoras/slides/BSDCan2012-BulletCache.pdf · Introducing the Bullet Cache 1.Offers a smarter data structure to the user side than a simple key-value pair 2.Implements

The main data structure

● A “forest of trees”, anchored in hash table buckets

● Buckets are directly addressed by hashing record keys

● Buckets are protected by rwlocks

RWlock node

node

node

node

node

node

Red-blacktree

RWlock node

node

node

node

node

node

Red-blacktree

hash value = H1

hash value = H2

. . .

tree root

tree root

Hash table

Page 15: Bullet Cache - FreeBSDivoras/slides/BSDCan2012-BulletCache.pdf · Introducing the Bullet Cache 1.Offers a smarter data structure to the user side than a simple key-value pair 2.Implements

Basic operation

1.Find h = Hash(key)

2.Acquire lock #h

3.Find record in RBtree indexed by key

4.Perform operation

5.Release lock #h

RWlock

node

node

node

node

node

node

Red-blacktree

RWlock

node

node

node

node

node

node

Red-blacktree

hash value = H1

hash value = H2

. . .

tree root

tree root

Hash table

1

2

3

4

5

OP

end

Page 16: Bullet Cache - FreeBSDivoras/slides/BSDCan2012-BulletCache.pdf · Introducing the Bullet Cache 1.Offers a smarter data structure to the user side than a simple key-value pair 2.Implements

Record tags follow a similar pattern

● The tags index the main structure and are maintained (almost) independently

Hash value = H1

RWlock

TK1 TK2 TK3 TK4

Hash value = H2

RWlock

TK1 TK2 TK3 TK4

...

Page 17: Bullet Cache - FreeBSDivoras/slides/BSDCan2012-BulletCache.pdf · Introducing the Bullet Cache 1.Offers a smarter data structure to the user side than a simple key-value pair 2.Implements

Concurrency and locking

● Concurrency is great – the default configuration starts 256 record buckets and 64 tag buckets

● Locking is without ordering assumptions– *_trylock() for everything– rollback-and-retry– No deadlocks

● Livelocks on the other hand need to be investigated

Page 18: Bullet Cache - FreeBSDivoras/slides/BSDCan2012-BulletCache.pdf · Introducing the Bullet Cache 1.Offers a smarter data structure to the user side than a simple key-value pair 2.Implements

Two-way linking betweenrecords and tags

RWlock node

node

node

node

node

node

RWlock node

node

node

node

node

node

hash value = H1

hash value = H2

. . .

tree root

tree root

Hash table

hash value = H1

RWlock

TK1 TK2 TK3 TK4

hash value = H2

RWlock

TK1 TK2 TK3 TK4

...

Page 19: Bullet Cache - FreeBSDivoras/slides/BSDCan2012-BulletCache.pdf · Introducing the Bullet Cache 1.Offers a smarter data structure to the user side than a simple key-value pair 2.Implements

Concurrency

● Scenario 1:– A record is

referenced → need to hold N tag bucket locks

● Scenario 2:– A tag is

referenced → need to hold M record bucket locks

4 8 16 32 64 128 256

0%

10%

20%

30%

40%

50%

60%

70%

80%

90%

100%

NCPU=64, SHARED NCPU=64, EXCLUSIVE

NCPU=8, SHARED NCPU=8, EXCLUSIVE

Number of hash table buckets (H)

Pe

rce

nta

ge

of u

nco

nte

ste

d lo

ck a

cqu

isiti

on

s (

U)

Percentage of uncontested lock acquisitions

Page 20: Bullet Cache - FreeBSDivoras/slides/BSDCan2012-BulletCache.pdf · Introducing the Bullet Cache 1.Offers a smarter data structure to the user side than a simple key-value pair 2.Implements

Multithreading models

● Aka “which thread does what”● Three basic tasks:

– T1: Connection acceptance– T2: Network IO– T3: Payload work

● The big question: how to distribute these into threads?

Page 21: Bullet Cache - FreeBSDivoras/slides/BSDCan2012-BulletCache.pdf · Introducing the Bullet Cache 1.Offers a smarter data structure to the user side than a simple key-value pair 2.Implements

Multithreading models

● SPED : Single process, event driven● SEDA : Staged, event-driven architecture● AMPED : Asymmetric, multi-process,

event-driven● SYMPED : Symmetric, multi-process,

event driven Model New connection handler

Network IO handler

Payload work

SPED 1 thread In connection thread In connection thread

SEDA 1 thread N1 threads N2 threads

SEDA-S 1 thread N threads N threads

AMPED 1 thread 1 thread N threads

SYMPED 1 thread N threads In network thread

Page 22: Bullet Cache - FreeBSDivoras/slides/BSDCan2012-BulletCache.pdf · Introducing the Bullet Cache 1.Offers a smarter data structure to the user side than a simple key-value pair 2.Implements

All the models are event-driven

● The “dumb” model: thread-per-connection

● Not really efficient– (FreeBSD has experimented with KSE and

M:N threading but that didn't work out)

● IO events: via kqueue(2)● Inter-thread synchronization: queues

signalled with CVs

Page 23: Bullet Cache - FreeBSDivoras/slides/BSDCan2012-BulletCache.pdf · Introducing the Bullet Cache 1.Offers a smarter data structure to the user side than a simple key-value pair 2.Implements

SPED

● Single-threaded, event-driven● Very efficient on

single-CPU systems● Most efficient if

the operation isvery fast (comparedto network IO andevent handling)

● Used in efficient Unix network servers

Page 24: Bullet Cache - FreeBSDivoras/slides/BSDCan2012-BulletCache.pdf · Introducing the Bullet Cache 1.Offers a smarter data structure to the user side than a simple key-value pair 2.Implements

SEDA

● Staged, event-driven● Different task threads

instantiated indifferent numbers

● Generally,N1 != N2 != N3

● The most queueing● The most separation

of tasks – most CPUs used

T1

T2

T2

T2

T3

T3

T3

T3

Page 25: Bullet Cache - FreeBSDivoras/slides/BSDCan2012-BulletCache.pdf · Introducing the Bullet Cache 1.Offers a smarter data structure to the user side than a simple key-value pair 2.Implements

AMPED

● Asymmetric multi-process event-driven● Asymmetric: N(T2) != N(T3)● Assumes network IO

processing is cheapcompared tooperation processing

● Moderate amount of queuing● Can use arbitrary number of CPUs

T1 T2 T3

T3

T3

Page 26: Bullet Cache - FreeBSDivoras/slides/BSDCan2012-BulletCache.pdf · Introducing the Bullet Cache 1.Offers a smarter data structure to the user side than a simple key-value pair 2.Implements

SYMPED

● Symmetric multi-process event-driven● Symmetric: grouping of tasks● Assumes network IO

and operation processing are similarlyexpensive but uniform

● Sequential processinginside threads

● Similar to multiple instances of SPED

T1

T2+T3

T2+T3

T2+T3

Page 27: Bullet Cache - FreeBSDivoras/slides/BSDCan2012-BulletCache.pdf · Introducing the Bullet Cache 1.Offers a smarter data structure to the user side than a simple key-value pair 2.Implements

Multithreading modelsin Bullet Cache

● Command-line configuration:– n : number of network threads– t : number of payload threads

● n=0, t=0 : SPED● n=1, t>0 : AMPED● n>0, t=0 : SYMPED● n>1, t>0 : SEDA● n>1, t>1, n=t : SEDA-S (symmetrical)

Page 28: Bullet Cache - FreeBSDivoras/slides/BSDCan2012-BulletCache.pdf · Introducing the Bullet Cache 1.Offers a smarter data structure to the user side than a simple key-value pair 2.Implements

How does that work?

● SEDA: the same network loop accepts connections and network IO

● Others: The network IO threads accept messages, then either:

– process them in-thread or – queue them on worker thread queues

● Response messages are either sent in-thread from whichever thread generates them or finished with the IO event code

Page 29: Bullet Cache - FreeBSDivoras/slides/BSDCan2012-BulletCache.pdf · Introducing the Bullet Cache 1.Offers a smarter data structure to the user side than a simple key-value pair 2.Implements

Performance of various models

20 40 60 80 100 120 140

0

50

100

150

200

250

300

350

400

450

500

SPED SEDA SEDA-S AMPED SYMPED

Number of clients

Th

ou

sa

nd

s o

f tra

ns

act

ion

s/s

Except in specialcircumstances,

SYMPED is best

Page 30: Bullet Cache - FreeBSDivoras/slides/BSDCan2012-BulletCache.pdf · Introducing the Bullet Cache 1.Offers a smarter data structure to the user side than a simple key-value pair 2.Implements

Why is SYMPED efficient?

● The same thread receives the message and processes it

● No queueing– No context switching– In the optimal case: no any kind of

(b)locking delays

● Downsides:– Serializes network IO and processing

within the thread (which is ok if per-CPU)

Page 31: Bullet Cache - FreeBSDivoras/slides/BSDCan2012-BulletCache.pdf · Introducing the Bullet Cache 1.Offers a smarter data structure to the user side than a simple key-value pair 2.Implements

Notable performance optimizations

● “zero-copy” operation– Queries which do not involve complex

processing or record aggregation are are satisfied directly from data structures

● “zero-malloc” operation– The code re-uses memory buffers as much

as possible; the fast path is completely malloc()- and memcpy()-free

● Adaptive dynamic buffer sizes– malloc() usage is tracked to avoid realloc()

Page 32: Bullet Cache - FreeBSDivoras/slides/BSDCan2012-BulletCache.pdf · Introducing the Bullet Cache 1.Offers a smarter data structure to the user side than a simple key-value pair 2.Implements

State of the art

92 185 278 371 464 558 651 744 837 930 1023 1395 1861 2792 3723

200.000 TPS

400.000 TPS

600.000 TPS

800.000 TPS

1.000.000 TPS

1.200.000 TPS

1.400.000 TPS

1.600.000 TPS

1.800.000 TPS

2.000.000 TPS

System A (June 2010) System B (Jan 2011) System B (Jun 2011)

System C (Dec 2011) System D (Mar 2012)

Average record data size

Pe

rfo

rma

nce

Page 33: Bullet Cache - FreeBSDivoras/slides/BSDCan2012-BulletCache.pdf · Introducing the Bullet Cache 1.Offers a smarter data structure to the user side than a simple key-value pair 2.Implements

State of the art

92 185 278 371 464 558 651 744 837 930 1023 1395 1861 2792 3723

200.000 TPS

400.000 TPS

600.000 TPS

800.000 TPS

1.000.000 TPS

1.200.000 TPS

1.400.000 TPS

1.600.000 TPS

1.800.000 TPS

2.000.000 TPS

System A (June 2010) System B (Jan 2011) System B (Jun 2011)

System C (Dec 2011) System D (Mar 2012)

Average record data size

Pe

rfo

rma

nce

Xeon 5675, 6-core, 3 GHzXeon 5675, 6-core, 3 GHz+HTT

9-stable, March 2012

Page 34: Bullet Cache - FreeBSDivoras/slides/BSDCan2012-BulletCache.pdf · Introducing the Bullet Cache 1.Offers a smarter data structure to the user side than a simple key-value pair 2.Implements

… under certain conditions

● The optimal, fast path (zero-memcpy, zero-malloc, optimal buffers)

– Which is actually less important, we know that these algorithms are fast...

● Using Unix domain sockets– Much more important– FreeBSD's network stack (the TCP path) is

currently basically nonscalable to SMP?– UDP path is more scalable … WIP

Page 35: Bullet Cache - FreeBSDivoras/slides/BSDCan2012-BulletCache.pdf · Introducing the Bullet Cache 1.Offers a smarter data structure to the user side than a simple key-value pair 2.Implements

TCP vs Unix sockets

104 209 314 420 525 639 735 840 945 1050 1576 2102 3153 42040 TPS

100,000 TPS

200,000 TPS

300,000 TPS

400,000 TPS

500,000 TPS

600,000 TPS

700,000 TPS

800,000 TPS

900,000 TPS

1,000,000 TPS

System D / mdcached System D / memcached System D / redis

Average record size

Page 36: Bullet Cache - FreeBSDivoras/slides/BSDCan2012-BulletCache.pdf · Introducing the Bullet Cache 1.Offers a smarter data structure to the user side than a simple key-value pair 2.Implements

NUMA Effects

1 2 3 4 5 6 7 8 9 10 15 20 30 400 TPS

200,000 TPS

400,000 TPS

600,000 TPS

800,000 TPS

1,000,000 TPS

1,200,000 TPS

1,400,000 TPS

1,600,000 TPS

1,800,000 TPS

2,000,000 TPS

System D System D / NUMA System D / ULE

cpuset(4)-bound to a single socket

cpuset(4) client & server separate sockets

No cpuset(4)only ULE

It's unlikely that better NUMA support would help at all...

Page 37: Bullet Cache - FreeBSDivoras/slides/BSDCan2012-BulletCache.pdf · Introducing the Bullet Cache 1.Offers a smarter data structure to the user side than a simple key-value pair 2.Implements

Scalability wrt number of records

1.000 10.000 100.000 1.000.000 10.000.000

300.000 TPS

320.000 TPS

340.000 TPS

360.000 TPS

380.000 TPS

400.000 TPS

420.000 TPS

440.000 TPS

mdcached

Page 38: Bullet Cache - FreeBSDivoras/slides/BSDCan2012-BulletCache.pdf · Introducing the Bullet Cache 1.Offers a smarter data structure to the user side than a simple key-value pair 2.Implements

Bells & whistles

● Binary protocol (endian-dependant)● Extensive atomic operation set

– cmpset, add, fetchadd, readandclear

● “tstack” operations– Every tag (tk,tv) identifies a stack– Push and pop operations on records

● Periodic data dumps / chekpoints– Cache pre-warm (load from file)

Page 39: Bullet Cache - FreeBSDivoras/slides/BSDCan2012-BulletCache.pdf · Introducing the Bullet Cache 1.Offers a smarter data structure to the user side than a simple key-value pair 2.Implements

Usage ideas

● Application data cache, database cache– Semantically tag cached records– Efficient retrieval and expiry (deletion)

● Primary data storage– High-performance ephemeral storage– Optional periodic checkpoints

● Data sharing between app server nodes● Esoteric: distributed lock manager, stack

Page 40: Bullet Cache - FreeBSDivoras/slides/BSDCan2012-BulletCache.pdf · Introducing the Bullet Cache 1.Offers a smarter data structure to the user side than a simple key-value pair 2.Implements

Bullet Cache

Balancing speed and usabilityin a cache server

http://www.sf.net/projects/mdcached

Ivan Voras <[email protected]>