@@ -53,7 +53,6 @@ Create a keyspace, and a table as mentioned above. Load data with:
5353 -p readproportion=0 -p updateproportion=0 \
5454 -p fieldcount=10 -p fieldlength=128 \
5555 -p insertstart=0 -p insertcount=1000000000 \
56- -p cassandra.coreconnections=14 -p cassandra.maxconnections=14 \
5756 -p cassandra.username=cassandra -p cassandra.password=cassandra \
5857 -p scylla.hosts=ip1,ip2,ip3,...
5958
@@ -63,27 +62,32 @@ Use as following:
6362 -target 120000 -threads 840 -p recordcount=1000000000 \
6463 -p fieldcount=10 -p fieldlength=128 \
6564 -p operationcount=50000000 \
66- -p scylla.coreconnections=280 -p scylla.maxconnections=280 \
6765 -p scylla.username=cassandra -p scylla.password=cassandra \
68- -p scylla.hosts=ip1,ip2,ip3,... \
69- -p scylla.tokenaware=true
66+ -p scylla.hosts=ip1,ip2,ip3,...
7067
7168## On choosing meaningful configuration
7269
7370### 1. Load target
7471
75- You want to test how a database handles load. To get the performance picture
76- you would want to look at the latency distribution and utilization under the
77- constant load. To select load use ` -target ` to state desired throughput level.
72+ Suppose, you want to test how a database handles an OLTP load.
73+
74+ In this case, to get the performance picture you want to look at the latency
75+ distribution and utilization at the sustained throughput that is independent
76+ of the processing speed. This kind of system called an open-loop system.
77+ Use the ` -target ` flag to state desired requests arrival rate.
7878
7979For example ` -target 120000 ` means that we expect YCSB workers to generate
80- 120,000 requests per second (RPS, QPS or TPS) to the database.
80+ 120,000 requests per second (RPS, QPS or TPS) overall to the database.
8181
82- Why is this important? Because without setting target throughput you will be
83- looking only on the system equilibrium point that in the face of constantly
84- varying latency will not allow you to see either throughput, nor latency.
82+ Why is this important? First, we want to look at the latency at some sustained
83+ throughput target, not visa versa. Second, without a throughput target,
84+ the system+loader pair will converge to the closed-loop system that has completely
85+ different characteristics than what we wanted to measure. The load will settle
86+ at the system equilibrium point. You will be able to find the throughput that will depend
87+ on the number of loader threads (workers) but not the latency - only service time.
88+ This is not something we expected.
8589
86- For more information check out these resources on the coordinated omission problem:
90+ For more information check out these resources on the coordinated omission problem.
8791
8892See
8993[[ 1]] ( http://highscalability.com/blog/2015/10/5/your-load-generator-is-probably-lying-to-you-take-the-red-pi.html )
9296and [[ this]] ( https://www.youtube.com/watch?v=lJ8ydIuPFeU )
9397great talk by Gil Tene.
9498
95- ### 2. Parallelism factor and threads
99+ ### 2. Latency correction
100+
101+ To measure latency, it is not enough to just set a target.
102+ The latencies must be measured with the correction as we apply
103+ a closed-class loader to the open-class problem. This is what YCSB
104+ calls an Intended operation.
105+
106+ Intended operations have points in time when they were intended to be executed
107+ according to the scheduler defined by the load target (--target). We must correct
108+ measurement if we did not manage to execute an operation in time.
109+
110+ The fair measurement consists of the operation latency and its correction
111+ to the point of its intended execution. Even if you don’t want to have
112+ a completely fair measurement, use “both”:
113+
114+ -p measurement.interval=both
115+
116+ Other options are “op” and “intended”. “op” is the default.
117+
118+ Another flag that affects measurement quality is the type of histogram
119+ “-p measurementtype” but for a long time, it uses “hdrhistogram” that
120+ must be fine for most use cases.
121+
122+ ### 3. Latency percentiles and multiple loaders
123+
124+ Latencies percentiles can't be averaged. Don't fall into this trap.
125+ Neither averages nor p99 averages do not make any sense.
126+
127+ If you run a single loader instance look for P99 - 99 percentile.
128+ If you run multiple loaders dump result histograms with:
129+
130+ -p measurement.histogram.verbose=true
131+
132+ or
133+
134+ -p hdrhistogram.fileoutput=true
135+ -p hdrhistogram.output.path=file.hdr
136+
137+ merge them manually and extract required percentiles out of the
138+ joined result.
139+
140+ Remember that running multiple workloads may distort original
141+ workloads distributions they were intended to produce.
142+
143+ ### 4. Parallelism factor and threads
96144
97145Scylla utilizes [ thread-per-core] ( https://www.scylladb.com/product/technology/ ) architecture design.
98146That means that a Node consists of shards that are mapped to the CPU cores 1-per-core.
@@ -113,41 +161,45 @@ of shards, and the number of nodes in the cluster. For example:
113161
114162 =>
115163
116- threads = K * shards * nodes = K * 14 * nodes
164+ threads = K * shards per node * nodes
117165
118166 for i3.4xlarge where
119167
120- - K is parallelism factor >= 1,
121- - Nodes is number of nodes in the cluster.
122-
123- For example for 3 nodes ` i3.4xlarge ` and ` -threads 840 ` means
124- ` K = 20 ` , ` shards = 14 ` , and ` threads = 14 * 20 * 3 ` .
168+ - K is parallelism factor:
125169
126- Thus, the ` K ` - the parallelism factor must be selected in the first order. If you
127- don't know what you want out of it start with 1.
170+ K >= Target Throughput / QPS per Worker / Shards per node / Nodes / Workers per shard >= 1
171+ where
172+ Target Throughput = --target
173+ QPS per Worker = 1000 [ms/second] / Latency in ms expected at target Percentile
174+ Shards per node = vCPU per cluster node - 2
175+ Nodes = a number of nodes in the cluster.
176+ Workers per shard = Target Throughput / Shards per node / Nodes / QPS per Worker
128177
129- For picking desired parallelism factor it is useful to come from desired ` target `
130- parameter. It is better if the ` target ` is a multiple of ` threads ` .
178+ - Nodes is number of nodes in the cluster.
131179
132180Another concern is that for high throughput scenarios you would probably
133181want to keep shards incoming queues non-empty. For that your parallelism factor
134182must be at least 2.
135183
136- ### 3 . Number of connections
184+ ### 5 . Number of connections
137185
138- Both ` scylla.coreconnections ` and ` scylla.maxconnections ` define limits
139- per node. When you see ` -p scylla.coreconnections=280 -p scylla.maxconnections=280 `
140- that means 280 connections per node.
186+ If you use original Cassandra drivers you need to pick the proper number
187+ of connections per host. Scylla drivers do not require this to be configured
188+ and by default create a connection per shard. For example if your node has
189+ 16 vCPU and thus 14 shards Scylla drivers will pick to create 14 connections
190+ per host. An excess of connections may result in degraded latency.
141191
142- Number of connections must be a multiple of:
192+ Database client protocol is asynchronous and allows queueing requests in
193+ a single connection. The default queue limit for local keys is 1024 and 256
194+ for remote ones. Current binding implementation do not require this.
143195
144- - number of _ shards_
145- - parallelism factor ` K `
196+ Both ` scylla.coreconnections ` and ` scylla.maxconnections ` define limits per node.
197+ When you see ` -p scylla.coreconnections=14 -p scylla.maxconnections=14 ` that means
198+ 14 connections per node.
146199
147- For example, for ` i3.4xlarge ` that has 14 shards per node and ` K = 20 `
148- it makes sense to pick ` connections = shards * K = 14 * 20 = 280 ` .
200+ Pick the number of connections per host to be divisible by the number of _ shards_ .
149201
150- ### 4 . Other considerations
202+ ### 6 . Other considerations
151203
152204Consistency levels do not change consistency model or its strongness.
153205Even with ` -p scylla.writeconsistencylevel=ONE ` the data will be written
@@ -159,16 +211,13 @@ latency picture a bit but would not affect utilization.
159211Remember that you can't measure CPU utilization with Scylla by normal
160212Unix tools. Check out Scylla own metrics to see real reactors utilization.
161213
162- Always use [ token aware] ( https://www.scylladb.com/2019/03/27/best-practices-for-scylla-applications/ )
163- load balancing ` -p scylla.tokenaware=true ` .
164-
165214For best performance it is crucial to evenly load all available shards.
166215
167- ### 5 . Expected performance target
216+ ### 7 . Expected performance target
168217
169218You can expect about 12500 uOPS / core (shard), where uOPS are basic
170219reads and writes operations post replication. Don't forget that usually
171- ` Core = 2 * vCPU ` for HT systems.
220+ ` Core = 2 vCPU ` for HT systems.
172221
173222For example if we insert a row with RF = 3 we can count at least 3 writes -
1742231 write per each replica. That is 1 Transaction = 3 u operations.
@@ -235,12 +284,9 @@ of 3 nodes of i3.4xlarge (16 vCPU per node) and target of 120000 is:
235284 * Default is false
236285 * https://docs.scylladb.com/using-scylla/tracing/
237286
238- - ` scylla.tokenaware `
239- - Enable token awareness
240- - Default value is false.
241-
242- - ` scylla.tokenaware_local_dc `
243- - Restrict Round Robin child policy with the local dc nodes
287+ * ` scylla.local_dc `
288+ - Specify local datacenter for multi-dc setup.
289+ - By default uses LOCAL_QUORUM consistency level.
244290 - Default value is empty.
245291
246292- ` scylla.lwt `
0 commit comments