Performance vs new features: it doesnt have to be a zero-sum game - - PowerPoint PPT Presentation

performance vs new features it doesn t have to be a zero
SMART_READER_LITE
LIVE PREVIEW

Performance vs new features: it doesnt have to be a zero-sum game - - PowerPoint PPT Presentation

Performance vs new features: it doesnt have to be a zero-sum game QCon London 2020 Dmitry Vyazelenko @DVyazelenko Do you trust your file system? Do you trust your file system? All File Systems are Not Created Equal: On the Complexity of


slide-1
SLIDE 1

QCon London 2020 Dmitry Vyazelenko @DVyazelenko

Performance vs new features: it doesn’t have to be a zero-sum game

slide-2
SLIDE 2

Do you trust your file system?

slide-3
SLIDE 3

Do you trust your file system?

All File Systems are Not Created Equal: On the Complexity of Crafting Crash Consistent Applications Pillai et al. 2014

slide-4
SLIDE 4

Do you trust your file system?

Table 1: Persistence Properties

slide-5
SLIDE 5

Do you trust your file system?

Table 2: Failure Consequences

slide-6
SLIDE 6

Do you trust your file system?

Redundancy does not imply fault tolerance: analysis of distributed storage reactions to single errors and corruptions Ganesan et al., FAST 2017

slide-7
SLIDE 7

Do you trust your file system?

We studied eight widely used distributed storage systems: Redis, ZooKeeper, Cassandra, Kafka, RethinkDB, MongoDB, LogCabin, and CockroachDB. We find that these systems can silently return corrupted data to users, lose data, propagate corrupted data to intact replicas become unavailable, or return an unexpected error

  • n queries.
slide-8
SLIDE 8

– Linus Torvalds

“Don't use ZFS. It's that simple. It was always more of a buzzword than anything else, I feel, and the licensing issues just make it a non-starter for me.”

https://www.realworldtech.com/forum/?threadid=189711&curpostid=189841

slide-9
SLIDE 9

CRC

A cyclic redundancy check (CRC) is an error-detecting code commonly used in digital networks and storage devices to detect accidental changes to raw data. Blocks

  • f data entering these systems get a short check value

attached, based on the remainder of a polynomial division of their contents.

slide-10
SLIDE 10

CRC in Java 8

slide-11
SLIDE 11

CRC in Java 8

package java.util.zip; public interface Checksum { public void update(int b); public void update(byte[] b, int off, int len); public long getValue(); public void reset(); }

slide-12
SLIDE 12

CRC in Java 8

public class CRC32 implements Checksum { /** * … * Upon return, the buffer's position will * be updated to its limit; its limit will not have been * changed. * * @param buffer the ByteBuffer to update the checksum with * @since 1.8 *0 public void update(ByteBuffer buffer) }

slide-13
SLIDE 13

CRC in Java 14

public interface Checksum { public void update(int b); default public void update(byte[] b) /0 @since 9 public void update(byte[] b, int off, int len); default public void update(ByteBuffer buffer) /0 @since 9 public long getValue(); public void reset(); }

slide-14
SLIDE 14

CRC in Java 8

slide-15
SLIDE 15

CRC in Java 8

final ByteBuffer buffer = ../; final int position = buffer.position(); final CRC32 checksum = new CRC32(); checksum.update(buffer); final int checksum = (int)checksum.getValue(); buffer.position(position);

slide-16
SLIDE 16

CRC in Java 8

😮

final ByteBuffer buffer = ../; final int position = buffer.position(); final CRC32 checksum = new CRC32(); checksum.update(buffer); final int checksum = (int)checksum.getValue(); buffer.position(position);

slide-17
SLIDE 17

How about…

public static int crc32(int crc, ByteBuffer buffer, int offset, int length)

slide-18
SLIDE 18

How about…

public static int crc32(int crc, ByteBuffer buffer, int offset, int length) public static int crc32(int crc, long address, int offset, int length)

slide-19
SLIDE 19

Digging deeper

public class CRC32 implements Checksum { private native static int update(int crc, int b); private native static int updateBytes(int crc, byte[] b, int off, int len); private native static int updateByteBuffer(int adler, long addr, int off, int len); }

slide-20
SLIDE 20

Digging deeper

public final class CRC32C implements Checksum { @HotSpotIntrinsicCandidate private static int updateBytes(int crc, byte[] b, int off, int end) @HotSpotIntrinsicCandidate private static int updateDirectByteBuffer(int crc, long address, int off, int end) }

slide-21
SLIDE 21

Baseline

JDK 8 (1.8.0_242-b20)

Millions of msg/sec 5 10 15 20 25 30 35 40 Record Replay

35 40

slide-22
SLIDE 22

Baseline

JDK 11 (11.0.6+10-LTS)

Millions of msg/sec 5 10 15 20 25 30 35 40 Record Replay

25 41

slide-23
SLIDE 23

Initial CRC support

JDK 8 (1.8.0_242-b20)

Millions of msg/sec 5 10 15 20 25 30 35 40 Record Record (CRC-32) Replay Replay (CRC-32)

21 34 25 40

slide-24
SLIDE 24

Initial CRC support

JDK 11 (11.0.6+10-LTS)

Millions of msg/sec 5 10 15 20 25 30 35 40 Record Record (CRC-32) Record (CRC-32C) Replay Replay (CRC-32) Replay (CRC-32C)

21 17 26 28 24 41

slide-25
SLIDE 25

CRC-32 vs CRC-32C

Execution time, ns 20 40 60 80 100 120 140 160 180 Input size in bytes 32 64 128 256 512 1024 2048 4096

CRC-32 CRC-32C

slide-26
SLIDE 26

CRC-32 vs CRC-32C

Execution time, ns 10 100 1000 10000 Input size in bytes 32 64 128 256 512 1024 2048 4096

CRC-32 CRC-32C Slicing by 8

slide-27
SLIDE 27

CRC-32 vs CRC-32C

Execution time, ns 10 100 1000 10000 Input size in bytes 32 64 128 256 512 1024 2048 4096

CRC-32 CRC-32C Slicing by 8

slide-28
SLIDE 28

How replay works

final int bytesRead = readRecording(); while (hasMoreFrames(bytesRead)) { final int frameLength = readFrame(); verifyChecksum(); if (publication.tryClaim(frameLength, bufferClaim)) { bufferClaim.putBytes(replayBuffer, offset, frameLength) .commit(); } }

slide-29
SLIDE 29

Let’s fix replay #1

final int bytesRead = readRecording(); while (hasMoreFrames(bytesRead)) { final int frameLength = readFrame(); verifyChecksum(); handleStartOfBatch(); if (publication.tryClaim(frameLength, endClaim)) { endClaim.putBytes(replayBuffer, offset, frameLength) .commit(); } handleEndOfBatch(); }

slide-30
SLIDE 30

Let’s fix replay #1

JDK 11 (11.0.6+10-LTS)

Millions of msg/sec 5 10 15 20 25 Replay Replay (CRC-32C) Fix#1 Fix#1 (CRC-32C)

22 27 21 26

slide-31
SLIDE 31

Let’s fix replay #2

final int bytesRead = readRecording(); while (hasMoreFrames(bytesRead)) { readFrame(); verifyChecksum(); prepareFrame(); } publication.offerBlock(replayBuffer, 0, endOfLastFrame);

slide-32
SLIDE 32

Let’s fix replay #2

JDK 8 (1.8.0_242-b20)

Millions of msg/sec 5 10 15 20 25 30 35 40 45 Record Record (CRC-32) Replay Replay (CRC-32)

30 49 25 40

slide-33
SLIDE 33

Let’s fix replay #2

JDK 11 (11.0.6+10-LTS)

Millions of msg/sec 5 10 15 20 25 30 35 40 45 Record Record (CRC-32C) Replay Replay (CRC-32C)

39 49 28 41

slide-34
SLIDE 34

Conclusions

  • Performance vs new features: it doesn’t have to be a

zero-sum game

  • Stay curious and keep on digging…