Merge "Add performance testing in Monasca persister"
This commit is contained in:
commit
6150eadf64
4
.gitignore
vendored
4
.gitignore
vendored
@ -13,4 +13,6 @@ cover/
|
||||
*egg-info/
|
||||
.testrepository/
|
||||
.stestr/
|
||||
*.sample
|
||||
*.sample
|
||||
perf/persister_perf_*/*.*
|
||||
perf/jmeter.log
|
||||
|
56
perf/README.md
Normal file
56
perf/README.md
Normal file
@ -0,0 +1,56 @@
|
||||
<!-- Change things from this point on -->
|
||||
|
||||
monasca-persister performance benchmarking
|
||||
=============
|
||||
|
||||
This tool benchmarkes the Monasca Persister performance and throughput.
|
||||
It uses JMeter and Kafka plugin to initiate Kafka metric messages and
|
||||
query the Dropwizard rest api to retrieve perister processing metrics.
|
||||
Becasue the Monasca persister python implementation does not have
|
||||
similar internal processing metric rest api availalbe, the support
|
||||
for python implementation performance benchmark will be added in a
|
||||
future release.
|
||||
|
||||
# Install
|
||||
|
||||
1. Download and install the latest Apache JMeter from
|
||||
http://jmeter.apache.org/download_jmeter.cgi.
|
||||
2. Add JMeter bin directory to the path, for example,
|
||||
PATH=$PATH:/opt/apache-jmeter/bin.
|
||||
3. Clone KafkaMeter repository: https://github.com/BrightTag/kafkameter.
|
||||
4. Run Maven package and install Kafkameter jar to $JMETER_HOME/lib/ext
|
||||
folder under the Apache JMeter installation home.
|
||||
|
||||
# Configure
|
||||
|
||||
1. Make a copy of the jmeter_test_plan.jmx file and modify the test plan
|
||||
to fit your goal. The available options are:
|
||||
- The number of threads(users)
|
||||
- The number of loops, i.e., the number of metric messages each thread/user
|
||||
will create)
|
||||
- The range of the random values in the metric name and dimension values.
|
||||
This controls the number of unique metric definitions the test plan will
|
||||
create.
|
||||
|
||||
The total number of metrics = the number of threads(users) * loop count.
|
||||
|
||||
# Run test
|
||||
|
||||
1. Execute persister_perf.sh, for example,
|
||||
```
|
||||
./persister_perf.sh -t jmeter_test_plan.jmx -n 1000000 -s 192.168.1.5,192.168.1.6 -p 8091 -w 10
|
||||
|
||||
-n the expected number of metric messages (equals to the number of threads(users) * loop count.
|
||||
-s a comma separated list of the Monasca Persister server hosts in the cluster
|
||||
-p Monasca Persister server port number
|
||||
-w the time to wait for before checking the processing status from the Monasca persister next time
|
||||
```
|
||||
|
||||
2. For each test run, an output folder (postfixed by the timestamp) is
|
||||
created. You can monitor the log file to watch the progress of jmeter
|
||||
sending messages, Monasca persister reading messages as well as
|
||||
Persister flushing the metrics into the time series database. It
|
||||
includes the accumulated number of metrics created, read and flushed
|
||||
and snapshots of throughput in each check interval.
|
||||
|
||||
3. The output file contains the summary of the performance testing result.
|
170
perf/jmeter_test_plan.jmx
Normal file
170
perf/jmeter_test_plan.jmx
Normal file
@ -0,0 +1,170 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<jmeterTestPlan version="1.2" properties="3.2" jmeter="3.3 r1808647">
|
||||
<hashTree>
|
||||
<TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Test Plan" enabled="true">
|
||||
<stringProp name="TestPlan.comments"></stringProp>
|
||||
<boolProp name="TestPlan.functional_mode">false</boolProp>
|
||||
<boolProp name="TestPlan.serialize_threadgroups">false</boolProp>
|
||||
<elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
|
||||
<collectionProp name="Arguments.arguments">
|
||||
<elementProp name="tenant" elementType="Argument">
|
||||
<stringProp name="Argument.name">tenant</stringProp>
|
||||
<stringProp name="Argument.value">t1</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
</collectionProp>
|
||||
</elementProp>
|
||||
<stringProp name="TestPlan.user_define_classpath"></stringProp>
|
||||
</TestPlan>
|
||||
<hashTree>
|
||||
<ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Thread Group" enabled="true">
|
||||
<stringProp name="ThreadGroup.on_sample_error">stoptest</stringProp>
|
||||
<elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true">
|
||||
<boolProp name="LoopController.continue_forever">false</boolProp>
|
||||
<stringProp name="LoopController.loops">80000000</stringProp>
|
||||
</elementProp>
|
||||
<stringProp name="ThreadGroup.num_threads">2</stringProp>
|
||||
<stringProp name="ThreadGroup.ramp_time">1</stringProp>
|
||||
<longProp name="ThreadGroup.start_time">1507913213000</longProp>
|
||||
<longProp name="ThreadGroup.end_time">1507913213000</longProp>
|
||||
<boolProp name="ThreadGroup.scheduler">false</boolProp>
|
||||
<stringProp name="ThreadGroup.duration"></stringProp>
|
||||
<stringProp name="ThreadGroup.delay"></stringProp>
|
||||
</ThreadGroup>
|
||||
<hashTree>
|
||||
<CounterConfig guiclass="CounterConfigGui" testclass="CounterConfig" testname="metric_Counter" enabled="true">
|
||||
<stringProp name="CounterConfig.start">1</stringProp>
|
||||
<stringProp name="CounterConfig.end">1000000</stringProp>
|
||||
<stringProp name="CounterConfig.incr">1</stringProp>
|
||||
<stringProp name="CounterConfig.name">metric_counter</stringProp>
|
||||
<stringProp name="CounterConfig.format"></stringProp>
|
||||
<boolProp name="CounterConfig.per_user">false</boolProp>
|
||||
</CounterConfig>
|
||||
<hashTree/>
|
||||
<RandomVariableConfig guiclass="TestBeanGUI" testclass="RandomVariableConfig" testname="Random Tenant ID" enabled="true">
|
||||
<stringProp name="maximumValue">10</stringProp>
|
||||
<stringProp name="minimumValue">1</stringProp>
|
||||
<stringProp name="outputFormat">tenant_00</stringProp>
|
||||
<boolProp name="perThread">true</boolProp>
|
||||
<stringProp name="randomSeed">${__Random(1, 1000000)}</stringProp>
|
||||
<stringProp name="variableName">tenant_id</stringProp>
|
||||
</RandomVariableConfig>
|
||||
<hashTree/>
|
||||
<RandomVariableConfig guiclass="TestBeanGUI" testclass="RandomVariableConfig" testname="Random Metric Name" enabled="true">
|
||||
<stringProp name="maximumValue">600</stringProp>
|
||||
<stringProp name="minimumValue">1</stringProp>
|
||||
<stringProp name="outputFormat">metric_000</stringProp>
|
||||
<boolProp name="perThread">true</boolProp>
|
||||
<stringProp name="randomSeed">${__Random(1000001, 2000000)}</stringProp>
|
||||
<stringProp name="variableName">metric_name</stringProp>
|
||||
</RandomVariableConfig>
|
||||
<hashTree/>
|
||||
<RandomVariableConfig guiclass="TestBeanGUI" testclass="RandomVariableConfig" testname="Random Host Dimension" enabled="true">
|
||||
<stringProp name="maximumValue">1500</stringProp>
|
||||
<stringProp name="minimumValue">1</stringProp>
|
||||
<stringProp name="outputFormat">host_0000</stringProp>
|
||||
<boolProp name="perThread">true</boolProp>
|
||||
<stringProp name="randomSeed">${__Random(3000001, 4000000)}</stringProp>
|
||||
<stringProp name="variableName">host_dim_value</stringProp>
|
||||
</RandomVariableConfig>
|
||||
<hashTree/>
|
||||
<RandomVariableConfig guiclass="TestBeanGUI" testclass="RandomVariableConfig" testname="Random Process Dimension" enabled="true">
|
||||
<stringProp name="maximumValue">20</stringProp>
|
||||
<stringProp name="minimumValue">1</stringProp>
|
||||
<stringProp name="outputFormat">process_000</stringProp>
|
||||
<boolProp name="perThread">true</boolProp>
|
||||
<stringProp name="randomSeed">${__Random(5000000, 10000000)}</stringProp>
|
||||
<stringProp name="variableName">process_dim_value</stringProp>
|
||||
</RandomVariableConfig>
|
||||
<hashTree/>
|
||||
<JavaSampler guiclass="JavaTestSamplerGui" testclass="JavaSampler" testname="kafka Request" enabled="true">
|
||||
<elementProp name="arguments" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" enabled="true">
|
||||
<collectionProp name="Arguments.arguments">
|
||||
<elementProp name="kafka_brokers" elementType="Argument">
|
||||
<stringProp name="Argument.name">kafka_brokers</stringProp>
|
||||
<stringProp name="Argument.value">192.168.1.2:9092,192.168.1.16:9092</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
<elementProp name="kafka_topic" elementType="Argument">
|
||||
<stringProp name="Argument.name">kafka_topic</stringProp>
|
||||
<stringProp name="Argument.value">metrics</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
<elementProp name="kafka_key" elementType="Argument">
|
||||
<stringProp name="Argument.name">kafka_key</stringProp>
|
||||
<stringProp name="Argument.value">${__time()}</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
<elementProp name="kafka_message" elementType="Argument">
|
||||
<stringProp name="Argument.name">kafka_message</stringProp>
|
||||
<stringProp name="Argument.value">{"metric":{"timestamp":${__time()},"name":"${metric_name}","dimensions":{"hostname":"${host_dim_value}","service":"monitoring", "process":"${__Random(1,22)}"},"value":${metric_counter},"value_meta":null},"meta":{"region":"RegionX","tenantId":"${tenant_id}"},"creation_time":${__time(/1000,)}}</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
<elementProp name="kafka_message_serializer" elementType="Argument">
|
||||
<stringProp name="Argument.name">kafka_message_serializer</stringProp>
|
||||
<stringProp name="Argument.value">org.apache.kafka.common.serialization.StringSerializer</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
<elementProp name="kafka_key_serializer" elementType="Argument">
|
||||
<stringProp name="Argument.name">kafka_key_serializer</stringProp>
|
||||
<stringProp name="Argument.value">org.apache.kafka.common.serialization.StringSerializer</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
<elementProp name="kafka_ssl_keystore" elementType="Argument">
|
||||
<stringProp name="Argument.name">kafka_ssl_keystore</stringProp>
|
||||
<stringProp name="Argument.value">${PARAMETER_KAFKA_SSL_KEYSTORE}</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
<elementProp name="kafka_ssl_keystore_password" elementType="Argument">
|
||||
<stringProp name="Argument.name">kafka_ssl_keystore_password</stringProp>
|
||||
<stringProp name="Argument.value">${PARAMETER_KAFKA_SSL_KEYSTORE_PASSWORD}</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
<elementProp name="kafka_ssl_truststore" elementType="Argument">
|
||||
<stringProp name="Argument.name">kafka_ssl_truststore</stringProp>
|
||||
<stringProp name="Argument.value">${PARAMETER_KAFKA_SSL_TRUSTSTORE}</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
<elementProp name="kafka_ssl_truststore_password" elementType="Argument">
|
||||
<stringProp name="Argument.name">kafka_ssl_truststore_password</stringProp>
|
||||
<stringProp name="Argument.value">${PARAMETER_KAFKA_SSL_TRUSTSTORE_PASSWORD}</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
<elementProp name="kafka_use_ssl" elementType="Argument">
|
||||
<stringProp name="Argument.name">kafka_use_ssl</stringProp>
|
||||
<stringProp name="Argument.value">false</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
<elementProp name="kafka_compression_type" elementType="Argument">
|
||||
<stringProp name="Argument.name">kafka_compression_type</stringProp>
|
||||
<stringProp name="Argument.value"></stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
<elementProp name="kafka_partition" elementType="Argument">
|
||||
<stringProp name="Argument.name">kafka_partition</stringProp>
|
||||
<stringProp name="Argument.value"></stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
</collectionProp>
|
||||
</elementProp>
|
||||
<stringProp name="classname">co.signal.kafkameter.KafkaProducerSampler</stringProp>
|
||||
</JavaSampler>
|
||||
<hashTree/>
|
||||
<Arguments guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="false">
|
||||
<collectionProp name="Arguments.arguments">
|
||||
<elementProp name="process_dim_value" elementType="Argument">
|
||||
<stringProp name="Argument.name">process_dim_value</stringProp>
|
||||
<stringProp name="Argument.value">${__javaScript(Math.floor(Math.random()*22),MYRESULT)}</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
</collectionProp>
|
||||
</Arguments>
|
||||
<hashTree/>
|
||||
</hashTree>
|
||||
</hashTree>
|
||||
<WorkBench guiclass="WorkBenchGui" testclass="WorkBench" testname="WorkBench" enabled="true">
|
||||
<boolProp name="WorkBench.save">true</boolProp>
|
||||
</WorkBench>
|
||||
<hashTree/>
|
||||
</hashTree>
|
||||
</jmeterTestPlan>
|
238
perf/jmeter_test_plan_mix.jmx
Normal file
238
perf/jmeter_test_plan_mix.jmx
Normal file
@ -0,0 +1,238 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<jmeterTestPlan version="1.2" properties="3.2" jmeter="3.3 r1808647">
|
||||
<hashTree>
|
||||
<TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Test Plan" enabled="true">
|
||||
<stringProp name="TestPlan.comments"></stringProp>
|
||||
<boolProp name="TestPlan.functional_mode">false</boolProp>
|
||||
<boolProp name="TestPlan.serialize_threadgroups">false</boolProp>
|
||||
<elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
|
||||
<collectionProp name="Arguments.arguments">
|
||||
<elementProp name="tenant" elementType="Argument">
|
||||
<stringProp name="Argument.name">tenant</stringProp>
|
||||
<stringProp name="Argument.value">t1</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
</collectionProp>
|
||||
</elementProp>
|
||||
<stringProp name="TestPlan.user_define_classpath"></stringProp>
|
||||
</TestPlan>
|
||||
<hashTree>
|
||||
<ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Monasca Tenant Thread Group" enabled="true">
|
||||
<stringProp name="ThreadGroup.on_sample_error">stoptest</stringProp>
|
||||
<elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true">
|
||||
<boolProp name="LoopController.continue_forever">false</boolProp>
|
||||
<stringProp name="LoopController.loops">1080</stringProp>
|
||||
</elementProp>
|
||||
<stringProp name="ThreadGroup.num_threads">4</stringProp>
|
||||
<stringProp name="ThreadGroup.ramp_time">1</stringProp>
|
||||
<longProp name="ThreadGroup.start_time">1510384829000</longProp>
|
||||
<longProp name="ThreadGroup.end_time">1510384829000</longProp>
|
||||
<boolProp name="ThreadGroup.scheduler">false</boolProp>
|
||||
<stringProp name="ThreadGroup.duration"></stringProp>
|
||||
<stringProp name="ThreadGroup.delay"></stringProp>
|
||||
</ThreadGroup>
|
||||
<hashTree>
|
||||
<CounterConfig guiclass="CounterConfigGui" testclass="CounterConfig" testname="metric_Counter" enabled="true">
|
||||
<stringProp name="CounterConfig.start">1</stringProp>
|
||||
<stringProp name="CounterConfig.end">1000000</stringProp>
|
||||
<stringProp name="CounterConfig.incr">1</stringProp>
|
||||
<stringProp name="CounterConfig.name">metric_counter</stringProp>
|
||||
<stringProp name="CounterConfig.format"></stringProp>
|
||||
<boolProp name="CounterConfig.per_user">false</boolProp>
|
||||
</CounterConfig>
|
||||
<hashTree/>
|
||||
<CounterConfig guiclass="CounterConfigGui" testclass="CounterConfig" testname="GuestHostCounter" enabled="true">
|
||||
<stringProp name="CounterConfig.start">1</stringProp>
|
||||
<stringProp name="CounterConfig.end"></stringProp>
|
||||
<stringProp name="CounterConfig.incr">50</stringProp>
|
||||
<stringProp name="CounterConfig.name">guestHostStartNum</stringProp>
|
||||
<stringProp name="CounterConfig.format"></stringProp>
|
||||
<boolProp name="CounterConfig.per_user">true</boolProp>
|
||||
</CounterConfig>
|
||||
<hashTree/>
|
||||
<LoopController guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true">
|
||||
<boolProp name="LoopController.continue_forever">true</boolProp>
|
||||
<stringProp name="LoopController.loops">10400000</stringProp>
|
||||
</LoopController>
|
||||
<hashTree>
|
||||
<ThroughputController guiclass="ThroughputControllerGui" testclass="ThroughputController" testname="Admin Throughput Controller" enabled="true">
|
||||
<intProp name="ThroughputController.style">1</intProp>
|
||||
<boolProp name="ThroughputController.perThread">false</boolProp>
|
||||
<intProp name="ThroughputController.maxThroughput">1</intProp>
|
||||
<FloatProperty>
|
||||
<name>ThroughputController.percentThroughput</name>
|
||||
<value>40.0</value>
|
||||
<savedValue>0.0</savedValue>
|
||||
</FloatProperty>
|
||||
<stringProp name="TestPlan.comments"> 1 mil unique metrics for admin tenants</stringProp>
|
||||
</ThroughputController>
|
||||
<hashTree>
|
||||
<JavaSampler guiclass="JavaTestSamplerGui" testclass="JavaSampler" testname="Admin kafka Request" enabled="true">
|
||||
<elementProp name="arguments" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" enabled="true">
|
||||
<collectionProp name="Arguments.arguments">
|
||||
<elementProp name="kafka_brokers" elementType="Argument">
|
||||
<stringProp name="Argument.name">kafka_brokers</stringProp>
|
||||
<stringProp name="Argument.value">192.168.1.2:9092,192.168.1.16:9092</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
<elementProp name="kafka_topic" elementType="Argument">
|
||||
<stringProp name="Argument.name">kafka_topic</stringProp>
|
||||
<stringProp name="Argument.value">metrics</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
<elementProp name="kafka_key" elementType="Argument">
|
||||
<stringProp name="Argument.name">kafka_key</stringProp>
|
||||
<stringProp name="Argument.value">${__time()}</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
<elementProp name="kafka_message" elementType="Argument">
|
||||
<stringProp name="Argument.name">kafka_message</stringProp>
|
||||
<stringProp name="Argument.value">{"metric":{"timestamp":${__time()},"name":"metric_${__Random(1,500)}","dimensions":{"hostname":"controller_${__Random(1,3)}","service":"service_${__Random(1,20)}", "process":"process_${__Random(1,33)}"},"value":${metric_counter},"value_meta":null},"meta":{"region":"RegionX","tenantId":"admin"},"creation_time":${__time(/1000,)}}</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
<elementProp name="kafka_message_serializer" elementType="Argument">
|
||||
<stringProp name="Argument.name">kafka_message_serializer</stringProp>
|
||||
<stringProp name="Argument.value">org.apache.kafka.common.serialization.StringSerializer</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
<elementProp name="kafka_key_serializer" elementType="Argument">
|
||||
<stringProp name="Argument.name">kafka_key_serializer</stringProp>
|
||||
<stringProp name="Argument.value">org.apache.kafka.common.serialization.StringSerializer</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
<elementProp name="kafka_ssl_keystore" elementType="Argument">
|
||||
<stringProp name="Argument.name">kafka_ssl_keystore</stringProp>
|
||||
<stringProp name="Argument.value">${PARAMETER_KAFKA_SSL_KEYSTORE}</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
<elementProp name="kafka_ssl_keystore_password" elementType="Argument">
|
||||
<stringProp name="Argument.name">kafka_ssl_keystore_password</stringProp>
|
||||
<stringProp name="Argument.value">${PARAMETER_KAFKA_SSL_KEYSTORE_PASSWORD}</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
<elementProp name="kafka_ssl_truststore" elementType="Argument">
|
||||
<stringProp name="Argument.name">kafka_ssl_truststore</stringProp>
|
||||
<stringProp name="Argument.value">${PARAMETER_KAFKA_SSL_TRUSTSTORE}</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
<elementProp name="kafka_ssl_truststore_password" elementType="Argument">
|
||||
<stringProp name="Argument.name">kafka_ssl_truststore_password</stringProp>
|
||||
<stringProp name="Argument.value">${PARAMETER_KAFKA_SSL_TRUSTSTORE_PASSWORD}</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
<elementProp name="kafka_use_ssl" elementType="Argument">
|
||||
<stringProp name="Argument.name">kafka_use_ssl</stringProp>
|
||||
<stringProp name="Argument.value">false</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
<elementProp name="kafka_compression_type" elementType="Argument">
|
||||
<stringProp name="Argument.name">kafka_compression_type</stringProp>
|
||||
<stringProp name="Argument.value"></stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
<elementProp name="kafka_partition" elementType="Argument">
|
||||
<stringProp name="Argument.name">kafka_partition</stringProp>
|
||||
<stringProp name="Argument.value"></stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
</collectionProp>
|
||||
</elementProp>
|
||||
<stringProp name="classname">co.signal.kafkameter.KafkaProducerSampler</stringProp>
|
||||
</JavaSampler>
|
||||
<hashTree/>
|
||||
</hashTree>
|
||||
<ThroughputController guiclass="ThroughputControllerGui" testclass="ThroughputController" testname="Guest Throughput Controller" enabled="true">
|
||||
<intProp name="ThroughputController.style">1</intProp>
|
||||
<boolProp name="ThroughputController.perThread">true</boolProp>
|
||||
<intProp name="ThroughputController.maxThroughput">1</intProp>
|
||||
<FloatProperty>
|
||||
<name>ThroughputController.percentThroughput</name>
|
||||
<value>60.0</value>
|
||||
<savedValue>0.0</savedValue>
|
||||
</FloatProperty>
|
||||
<stringProp name="TestPlan.comments">3 mil unique metric definitions</stringProp>
|
||||
</ThroughputController>
|
||||
<hashTree>
|
||||
<JavaSampler guiclass="JavaTestSamplerGui" testclass="JavaSampler" testname="Guest kafka Request" enabled="true">
|
||||
<elementProp name="arguments" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" enabled="true">
|
||||
<collectionProp name="Arguments.arguments">
|
||||
<elementProp name="kafka_brokers" elementType="Argument">
|
||||
<stringProp name="Argument.name">kafka_brokers</stringProp>
|
||||
<stringProp name="Argument.value">192.168.1.2:9092,192.168.1.16:9092</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
<elementProp name="kafka_topic" elementType="Argument">
|
||||
<stringProp name="Argument.name">kafka_topic</stringProp>
|
||||
<stringProp name="Argument.value">metrics</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
<elementProp name="kafka_key" elementType="Argument">
|
||||
<stringProp name="Argument.name">kafka_key</stringProp>
|
||||
<stringProp name="Argument.value">${__time()}</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
<elementProp name="kafka_message" elementType="Argument">
|
||||
<stringProp name="Argument.name">kafka_message</stringProp>
|
||||
<stringProp name="Argument.value">{"metric":{"timestamp":${__time()},"name":"metric_${__Random(501,600)}","dimensions":{"hostname":"host_${__intSum(${guestHostStartNum},${__Random(0,499)})}","service":"service_${__Random(1,2)}", "process":"process_${__Random(1,3)}"},"value":${metric_counter},"value_meta":null},"meta":{"region":"RegionX","tenantId":"tenant_${__Random(0,10)}"},"creation_time":${__time(/1000,)}}</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
<elementProp name="kafka_message_serializer" elementType="Argument">
|
||||
<stringProp name="Argument.name">kafka_message_serializer</stringProp>
|
||||
<stringProp name="Argument.value">org.apache.kafka.common.serialization.StringSerializer</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
<elementProp name="kafka_key_serializer" elementType="Argument">
|
||||
<stringProp name="Argument.name">kafka_key_serializer</stringProp>
|
||||
<stringProp name="Argument.value">org.apache.kafka.common.serialization.StringSerializer</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
<elementProp name="kafka_ssl_keystore" elementType="Argument">
|
||||
<stringProp name="Argument.name">kafka_ssl_keystore</stringProp>
|
||||
<stringProp name="Argument.value">${PARAMETER_KAFKA_SSL_KEYSTORE}</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
<elementProp name="kafka_ssl_keystore_password" elementType="Argument">
|
||||
<stringProp name="Argument.name">kafka_ssl_keystore_password</stringProp>
|
||||
<stringProp name="Argument.value">${PARAMETER_KAFKA_SSL_KEYSTORE_PASSWORD}</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
<elementProp name="kafka_ssl_truststore" elementType="Argument">
|
||||
<stringProp name="Argument.name">kafka_ssl_truststore</stringProp>
|
||||
<stringProp name="Argument.value">${PARAMETER_KAFKA_SSL_TRUSTSTORE}</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
<elementProp name="kafka_ssl_truststore_password" elementType="Argument">
|
||||
<stringProp name="Argument.name">kafka_ssl_truststore_password</stringProp>
|
||||
<stringProp name="Argument.value">${PARAMETER_KAFKA_SSL_TRUSTSTORE_PASSWORD}</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
<elementProp name="kafka_use_ssl" elementType="Argument">
|
||||
<stringProp name="Argument.name">kafka_use_ssl</stringProp>
|
||||
<stringProp name="Argument.value">false</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
<elementProp name="kafka_compression_type" elementType="Argument">
|
||||
<stringProp name="Argument.name">kafka_compression_type</stringProp>
|
||||
<stringProp name="Argument.value"></stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
<elementProp name="kafka_partition" elementType="Argument">
|
||||
<stringProp name="Argument.name">kafka_partition</stringProp>
|
||||
<stringProp name="Argument.value"></stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
</collectionProp>
|
||||
</elementProp>
|
||||
<stringProp name="classname">co.signal.kafkameter.KafkaProducerSampler</stringProp>
|
||||
</JavaSampler>
|
||||
<hashTree/>
|
||||
</hashTree>
|
||||
</hashTree>
|
||||
</hashTree>
|
||||
</hashTree>
|
||||
<WorkBench guiclass="WorkBenchGui" testclass="WorkBench" testname="WorkBench" enabled="true">
|
||||
<boolProp name="WorkBench.save">true</boolProp>
|
||||
</WorkBench>
|
||||
<hashTree/>
|
||||
</hashTree>
|
||||
</jmeterTestPlan>
|
164
perf/persister_perf.sh
Executable file
164
perf/persister_perf.sh
Executable file
@ -0,0 +1,164 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright 2017 SUSE LLC.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
PORT=8091
|
||||
CHECK_INTERVAL=30
|
||||
TIME_STAMP=$(date +%s)
|
||||
|
||||
mkdir persister_perf_${TIME_STAMP}
|
||||
|
||||
usage()
|
||||
{
|
||||
echo "usage: persister_perf.sh [[-s servers (required)] [-p port] \
|
||||
[-t JMeter test plan file] [-n number of metrics to insert (required)] \
|
||||
[-w wait time (seconds) betweenchecking persister status] | [-h help ]]"
|
||||
exit
|
||||
}
|
||||
|
||||
log()
|
||||
{
|
||||
# echo "$1"
|
||||
echo "$1" >> persister_perf_${TIME_STAMP}/persister_perf.log
|
||||
}
|
||||
|
||||
output()
|
||||
{
|
||||
# echo "$1"
|
||||
echo "$1" >> persister_perf_${TIME_STAMP}/persister_perf_output.txt
|
||||
}
|
||||
|
||||
get_received_metric_count_per_host()
|
||||
{
|
||||
local msg_count=$(curl -m 60 -s http://$1:$PORT/metrics?pretty=true | \
|
||||
jq '[.meters | with_entries(select(.key|match("monasca.persister.pipeline.event.MetricHandler\\[metric-[0-9]*\\].events-processed-meter";"i")))[] | .count] | add')
|
||||
echo "$msg_count"
|
||||
}
|
||||
|
||||
get_total_received_metric_count()
|
||||
{
|
||||
local count=0
|
||||
for server in $SERVERS; do
|
||||
local count_per_host=$(get_received_metric_count_per_host $server)
|
||||
log "$(date) Persister host: $server; Received metrics: $count_per_host"
|
||||
count=$((count + count_per_host))
|
||||
done
|
||||
log "$(date) Total received metrics: $count"
|
||||
echo "$count"
|
||||
}
|
||||
|
||||
get_flushed_metric_count_per_host()
|
||||
{
|
||||
local msg_count=$(curl -m 60 -s http://$1:$PORT/metrics?pretty=true \
|
||||
| jq '[.meters | with_entries(select(.key|match("monasca.persister.pipeline.event.MetricHandler\\[metric-[0-9]*\\].flush-meter";"i")))[] | .count] | add')
|
||||
echo "$msg_count"
|
||||
}
|
||||
|
||||
get_total_flushed_metric_count()
|
||||
{
|
||||
local count=0
|
||||
for server in $SERVERS; do
|
||||
local count_per_host=$(get_flushed_metric_count_per_host $server)
|
||||
log "$(date) Persister host: $server; Flushed metrics: $count_per_host"
|
||||
count=$((count + count_per_host))
|
||||
done
|
||||
log "$(date) Total flushed metrics: $count"
|
||||
echo "$count"
|
||||
}
|
||||
|
||||
|
||||
while getopts "hs:p:t:n:w:" option; do
|
||||
case "${option}" in
|
||||
h) usage;;
|
||||
s) declare -a SERVERS=$(echo "${OPTARG}" | sed "s/,/\n/g");;
|
||||
p) PORT=${OPTARG};;
|
||||
t) TEST_PLAN=${OPTARG};;
|
||||
n) NUM_METRICS=${OPTARG};;
|
||||
w) CHECK_INTERVAL=${OPTARG};;
|
||||
*) exit 1;;
|
||||
:) echo "Missing option argument for -$OPTARG" >&2; exit 1;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ ! "$SERVERS" ] || [ ! "$NUM_METRICS" ]; then
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log "starting JMeter run $TEST_PLAN"
|
||||
|
||||
jmeter -n -t $TEST_PLAN -l persister_perf_${TIME_STAMP}/jmeter.jnl -e \
|
||||
-o persister_perf_${TIME_STAMP}/jmeter \
|
||||
>> persister_perf_${TIME_STAMP}/persister_perf.log 2>&1 &
|
||||
|
||||
START_TIME=$(date +%s)
|
||||
|
||||
received_metric_count_start=$(get_total_received_metric_count)
|
||||
output "Total received metric count at start: $received_metric_count_start"
|
||||
|
||||
flushed_metric_count_start=$(get_total_flushed_metric_count)
|
||||
output "Total flushed metric count at start: $flushed_metric_count_start"
|
||||
|
||||
received_metric_count_orig=$((received_metric_count_start))
|
||||
|
||||
flushed_metric_count_orig=$((flushed_metric_count_start))
|
||||
|
||||
target_received_metric_count=$((received_metric_count_start + NUM_METRICS))
|
||||
|
||||
target_flushed_metric_count=$((flushed_metric_count_start + NUM_METRICS))
|
||||
|
||||
sleep $CHECK_INTERVAL
|
||||
|
||||
INTERVAL_END_TIME=$(date +%s)
|
||||
received_metric_count=$(get_total_received_metric_count)
|
||||
flushed_metric_count=$(get_total_flushed_metric_count)
|
||||
|
||||
while [ "$received_metric_count" -lt "$target_received_metric_count" \
|
||||
-o "$flushed_metric_count" -lt "$target_flushed_metric_count" ]
|
||||
do
|
||||
INTERVAL_START_TIME=$((INTERVAL_END_TIME))
|
||||
received_metric_count_start=$((received_metric_count))
|
||||
flushed_metric_count_start=$((flushed_metric_count))
|
||||
|
||||
sleep $CHECK_INTERVAL
|
||||
INTERVAL_END_TIME=$(date +%s)
|
||||
received_metric_count=$(get_total_received_metric_count)
|
||||
flushed_metric_count=$(get_total_flushed_metric_count)
|
||||
|
||||
log "Current received metric throughput: \
|
||||
$((($received_metric_count - $received_metric_count_start) \
|
||||
/ $(($INTERVAL_END_TIME - $INTERVAL_START_TIME))))"
|
||||
log "Current flushed metric throughput: \
|
||||
$((($flushed_metric_count - $flushed_metric_count_start) \
|
||||
/ $(($INTERVAL_END_TIME - $INTERVAL_START_TIME))))"
|
||||
log "Average received metric throughput: \
|
||||
$((($received_metric_count - $received_metric_count_orig) \
|
||||
/ $(($INTERVAL_END_TIME - $START_TIME))))"
|
||||
log "Average flushed metric throughput: \
|
||||
$((($flushed_metric_count - $flushed_metric_count_orig) \
|
||||
/ $(($INTERVAL_END_TIME - $START_TIME))))"
|
||||
log "Expect $((target_flushed_metric_count - flushed_metric_count)) \
|
||||
more metrics to be flushed"
|
||||
done
|
||||
|
||||
END_TIME=$(date +%s)
|
||||
ELAPSED=$(($END_TIME - $START_TIME))
|
||||
output "Total received metric count at end: $received_metric_count"
|
||||
output "Total flushed metric count at end: $flushed_metric_count"
|
||||
output "Total elapsed time: $ELAPSED"
|
||||
output "Average received metrics/second: \
|
||||
$((($received_metric_count - $received_metric_count_orig) / $ELAPSED))"
|
||||
output "Average persisted metrics/second: \
|
||||
$((($flushed_metric_count - $flushed_metric_count_orig) / $ELAPSED))"
|
Loading…
x
Reference in New Issue
Block a user