Seastar / ScyllaDB, or how we implemented a 10-times faster Cassandra

43
Nadav Har'El, ScyllaDB The Generalist Engineer meetup, Tel-Aviv Ides of March, 2016 Seastar Seastar Or how we implemented a 10-times faster Cassandra

Transcript of Seastar / ScyllaDB, or how we implemented a 10-times faster Cassandra

Page 1: Seastar / ScyllaDB,  or how we implemented a 10-times faster Cassandra

Nadav Har'El, ScyllaDB

The Generalist Engineer meetup, Tel-AvivIdes of March, 2016

SeastarSeastar Or how we implemented a10-times faster Cassandra

Page 2: Seastar / ScyllaDB,  or how we implemented a 10-times faster Cassandra

2

● Israeli but multi-national startup company– 15 developers cherry-picked from 10 countries.

● Founded 2013 (“Cloudius Systems”)– by Avi Kivity and Dor Laor of KVM fame.

● Fans of open-source: OSv, Seastar, ScyllaDB.

Page 3: Seastar / ScyllaDB,  or how we implemented a 10-times faster Cassandra

3

Make Cassandra 10 times faster

Your mission, should you choose to accept it:

Page 4: Seastar / ScyllaDB,  or how we implemented a 10-times faster Cassandra

4

“Make Cassandra 10 times faster”

● Why 10?● Why Cassandra?

– Popular NoSQL database (2nd to MongoDB).

– Powerful and widely applicable.

– Example of a wider class of middleware.

● Why “mission impossible”?– Cassandra not considered particularly slow -

– Considered faster than MongoDB, Hbase, et al.

– “disk is bottleneck” (no longer, with SSD!)

Page 5: Seastar / ScyllaDB,  or how we implemented a 10-times faster Cassandra

5

Our first attempt: OSv

● New OS design specifically for cloud VMs:– Run a single application per VM (“unikernel”)– Run existing Linux applications (Cassandra)– Run these faster than Linux.

Page 6: Seastar / ScyllaDB,  or how we implemented a 10-times faster Cassandra

6

OSv

● Some of the many ideas we used in OSv:– Single address space.– System call is just a function call.– Faster context switches.– No spin locks.– Smaller code.– Redesigned network stack (Van Jacobson).

Page 7: Seastar / ScyllaDB,  or how we implemented a 10-times faster Cassandra

7

OSv

● Writing an entire OS from scratch was a really fun exercise for our generalist engineers.

● Full description of OSv is beyond the scope of this talk. Check out:– “OSv—Optimizing the Operating System for Virtual

Machines”, Usenix ATC 2014.

Page 8: Seastar / ScyllaDB,  or how we implemented a 10-times faster Cassandra

8

Cassandra on OSv

● Cassandra-stress, READ, 4 vcpu:

On OSv, 34% faster than Linux

● Very nice, but not even close to our goal.

What are the remaining bottlenecks?

Page 9: Seastar / ScyllaDB,  or how we implemented a 10-times faster Cassandra

9

Bottlenecks: API locks

● In one profile, we saw 20% of run on lock() and unlock() operations. Most uncontended– Posix APIs allow threads to share

● file descriptors● sockets

– As many as 20 lock/unlock for each network packet!

● Uncontended locks were efficient on UP (flag to disable preemption), But atomic operations slow on many cores.

Page 10: Seastar / ScyllaDB,  or how we implemented a 10-times faster Cassandra

10

Bottlenecks: API copies

● Write/send system calls copies user data to kernel– Even on OSv with no user-kernel separation

– Part of the socket API

● Similar for read

Page 11: Seastar / ScyllaDB,  or how we implemented a 10-times faster Cassandra

11

Bottlenecks: context switching

● One thread per CPU is optimal, >1 require:– Context switch time

– Stacks consume memory and polute CPU cache

– Thread imbalance

● Requires fully non-blocking APIs– Cassandra's uses mmap() for disk….

Page 12: Seastar / ScyllaDB,  or how we implemented a 10-times faster Cassandra

12

Bottlenecks: unscalable applications

● Contended locks ruin scalability to many cores– Memcache's counter and shared cache

● Solution: per-cpu data.

● Even lock-free atomic algorithms are unscalable– Cache line bouncing

● Again, better to shard, not share, data.

– Becomes worse as core count grows

● NUMA

Page 13: Seastar / ScyllaDB,  or how we implemented a 10-times faster Cassandra

13

Therefore

● Need to provide a better APIs for server applications– Not file descriptors, sockets, threads, etc.

● Need to write better applications.

Page 14: Seastar / ScyllaDB,  or how we implemented a 10-times faster Cassandra

14

Framework

● One thread per CPU– Event-driven programming

– Everything (network & disk) is non-blocking

– How to write complex applications?

Page 15: Seastar / ScyllaDB,  or how we implemented a 10-times faster Cassandra

15

Framework

● Sharded (shared-nothing) applications– Important!

Page 16: Seastar / ScyllaDB,  or how we implemented a 10-times faster Cassandra

16

Framework

● Language with no runtime overheads or built-in data sharing

Page 17: Seastar / ScyllaDB,  or how we implemented a 10-times faster Cassandra

17

Seastar

● C++14 library● For writing new high-performance server applications● Share-nothing model, fully asynchronous● Futures & Continuations based

– Unified API for all asynchronous operations– Compose complex asyncrhonous operations– The key to complex applications

● (Optionally) full zero-copy user-space TCP/IP (over DPDK)● Open source: http://www.seastar-project.org/

Page 18: Seastar / ScyllaDB,  or how we implemented a 10-times faster Cassandra

18

Seastar linear scaling in #cores

Page 19: Seastar / ScyllaDB,  or how we implemented a 10-times faster Cassandra

19

Seastar linear scaling in #cores

Page 20: Seastar / ScyllaDB,  or how we implemented a 10-times faster Cassandra

20

Brief introduction to Seastar

Page 21: Seastar / ScyllaDB,  or how we implemented a 10-times faster Cassandra

21

Sharded application design

● One thread per CPU● Each thread handles one shard of data

– No shared data (“share nothing”)

– Separate memory per CPU (NUMA aware)

– Message-passing between CPUs

– No locks or cache line bounces

● Reactor (event loop) per thread● User-space network stack also sharded

Page 22: Seastar / ScyllaDB,  or how we implemented a 10-times faster Cassandra

22

Futures and continuations

● Futures and continuations are the building blocks of asynchronous programming in Seastar.

● Can be composed together to a large, complex, asynchronous program.

Page 23: Seastar / ScyllaDB,  or how we implemented a 10-times faster Cassandra

23

Futures and continuations

● A future is a result which may not be available yet:– Data buffer from the network

– Timer expiration

– Completion of a disk write

– The result of a computation which requires the values from one or more other futures.

● future<int>

● future<>

Page 24: Seastar / ScyllaDB,  or how we implemented a 10-times faster Cassandra

24

Futures and continuations

● An asynchronous function (also “promise”) is a function returning a future:– future<> sleep(duration)

– future<temporary_buffer<char>> read()

● The function sets up for the future to be fulfilled– sleep() sets a timer to fulfill the future it returns

Page 25: Seastar / ScyllaDB,  or how we implemented a 10-times faster Cassandra

25

Futures and continuations

● A continuation is a callback, typically a lambda executed when a future becomes ready– sleep(1s).then([] { std::cerr << “done”;});

● A continuation can hold state (lambda capture)– future<int> slow_incr(int i) { sleep(10ms).then( [i] { return i+1; });}

Page 26: Seastar / ScyllaDB,  or how we implemented a 10-times faster Cassandra

26

Futures and continuations

● Continuations can be nested:– future<int> get();future<> put(int);get().then([] (int value) { put(value+1).then([] { std::cout << “done”; });});

● Or chained:– get().then([] (int value) { return put(value+1);}).then([] { std::cout << “done”;});

Page 27: Seastar / ScyllaDB,  or how we implemented a 10-times faster Cassandra

27

Futures and continuations

● Parallelism is easy:– sleep(100ms).then([] { std::cout << “100ms\n”;});sleep(200ms).then([] { std::cout << “200ms\n”;

Page 28: Seastar / ScyllaDB,  or how we implemented a 10-times faster Cassandra

28

Futures and continuations

● In Seastar, every asynchronous operation is a future:– Network read or write

– Disk read or write

– Timers

– …

– A complex combination of other futures

● Useful for everything from writing network stack to writing a full, complex, application.

Page 29: Seastar / ScyllaDB,  or how we implemented a 10-times faster Cassandra

29

Network zero-copy

● future<temporary_buffer>input_stream::read()– temporary_buffer points at driver-provided pages, if

possible.

– Automatically discarded after use (C++).

● future<> output_stream::write(temporary_buffer)– Future becomes ready when TCP window allows further

writes (usually immediately).

– Buffer discarded after data is ACKed.

Page 30: Seastar / ScyllaDB,  or how we implemented a 10-times faster Cassandra

30

Two TCP/IP implementations

Networking API

Seastar (native) Stack POSIX (hosted) stack

Linux kernel (sockets)

User-space TCP/IP

Interface layer

DPDK

Virtio Xen

igb ixgb

Page 31: Seastar / ScyllaDB,  or how we implemented a 10-times faster Cassandra

31

Disk I/O

● Asynchronous and zero copy, using AIO and O_DIRECT.

● Not implemented well by all filesystems– XFS recommended

● Focusing on SSD● Future thought:

– Direct NVMe support,

– Implement filesystem in Seastar.

Page 32: Seastar / ScyllaDB,  or how we implemented a 10-times faster Cassandra

32

More info on Seastar

● http://seastar-project.com● https://github.com/scylladb/seastar● http://docs.seastar-project.org/● http://docs.seastar-project.org/master/md_doc_tu

torial.html

Page 33: Seastar / ScyllaDB,  or how we implemented a 10-times faster Cassandra

33

ScyllaDB

● NoSQL database, implemented in Seastar.● Fully compatible with Cassandra:

– Same CQL queries

– Copy over a complete Cassandra database

– Use existing drivers

– Use existing cassandra.yaml

– Use same nodetool or JMX console

– Can be clustered (of course...)

Page 34: Seastar / ScyllaDB,  or how we implemented a 10-times faster Cassandra

34

ScyllaDBCassandra

Key cache

Row cache

On-heap /Off-heap

Linux page cache

SSTables

Unified cache

SSTables

● Don't double-cache.● Don't cache unrelated rows.● Don't cache unparsed sstables.● Can fit much more into cache.● No page faults, threads, etc.

Page 35: Seastar / ScyllaDB,  or how we implemented a 10-times faster Cassandra

35

Scylla vs. Cassandra

● Single node benchmark:– 2 x 12-core x 2 hyperthread Intel(R) Xeon(R) CPU

E5-2690 v3 @ 2.60GHz

cassandra-stress Benchmark

ScyllaDB Cassandra

Write 1,871,556 251,785

Read 1,585,416 95,874

Mixed 1,372,451 108,947

Page 36: Seastar / ScyllaDB,  or how we implemented a 10-times faster Cassandra

36

Scylla vs. Cassandra

● We really got a x7 – x16 speedup!● Read speeded up more -

– Cassandra writes are simpler

– Row-cache benefits further improve Scylla's read

● Almost 2 million writes per second on single machine!– Google reported in their blogs achieving 1 million writes

per second on 330 (!) machines

– (2 years ago, and RF=3… but still impressive).

Page 37: Seastar / ScyllaDB,  or how we implemented a 10-times faster Cassandra

37

Scylla vs. Cassandra3 node cluster, 2x12 cores each; RF=3, CL=quorum

Page 38: Seastar / ScyllaDB,  or how we implemented a 10-times faster Cassandra

38

Better latency, at all load levels

Page 39: Seastar / ScyllaDB,  or how we implemented a 10-times faster Cassandra

39

What will you do with 10x performance?

● Shrink your cluster by a factor of 10● Use stronger (but slower) data models● Run more queries - more value from your data● Stop using caches in front of databases

Page 40: Seastar / ScyllaDB,  or how we implemented a 10-times faster Cassandra

40

Page 41: Seastar / ScyllaDB,  or how we implemented a 10-times faster Cassandra

41

Do we qualify?

In 3 years, our small team wrote:● A complete kernel and library (OSv).● An asynchronous programming framework

(Seastar).● A complete Cassandra-compatible NoSQL

database (ScyllaDB).

Page 42: Seastar / ScyllaDB,  or how we implemented a 10-times faster Cassandra

42

Page 43: Seastar / ScyllaDB,  or how we implemented a 10-times faster Cassandra

43

This project has received funding from the European Union’s Horizon 2020 research and innovation programme under grant agreement No 645402.