{"componentChunkName":"component---src-templates-article-single-page-js","path":"/post/smartcat-labs-berserker","result":{"pageContext":{"obj_id":"bbcb1335-9a12-500a-a6e6-ab15920ef1b1","node":{"content":"<p>Load generator with modular architecture.</p><p><a href=\"https://travis-ci.org/smartcat-labs/berserker\" rel=\"nofollow\"><img src=\"https://camo.githubusercontent.com/8ac158e9462f9535c5012441dd3a9bf79a8b706a/68747470733a2f2f7472617669732d63692e6f72672f736d6172746361742d6c6162732f6265727365726b65722e7376673f6272616e63683d6d6173746572\" alt=\"Build Status\" data-canonical-src=\"https://travis-ci.org/smartcat-labs/berserker.svg?branch=master\" /></a>\n<a href=\"https://bintray.com/smartcat-labs/maven/berserker/_latestVersion\" rel=\"nofollow\"> <img src=\"https://camo.githubusercontent.com/5ab44ddb3c261cc5f0e932342329abb69ff7e3ca/68747470733a2f2f6170692e62696e747261792e636f6d2f7061636b616765732f736d6172746361742d6c6162732f6d6176656e2f6265727365726b65722f696d616765732f646f776e6c6f61642e737667\" alt=\"Download\" data-canonical-src=\"https://api.bintray.com/packages/smartcat-labs/maven/berserker/images/download.svg\" /></a></p><p>Berserker is designed to be modular from beginning as illustrated on the following diagram.</p><p><a target=\"_blank\" href=\"https://github.com/smartcat-labs/berserker/blob/dev/images/core-design.png\"><img src=\"https://github.com/smartcat-labs/berserker/raw/dev/images/core-design.png\" alt=\"Core Design\" /></a></p><p>Rate generator controls the rate at which load generator operates, rate is expressed on per second basis, or better say, number of impulses which will be generated within one second. Each time impulse is generated load generator fetches data from data source and passes it to worker. Since those are simple interfaces, it is easy to add additional module implementing either data source, worker and even rate generator.\nFollowing diagram represents possible modules for Load Generator of which some are already implemented.</p><p><a target=\"_blank\" href=\"https://github.com/smartcat-labs/berserker/blob/dev/images/architecture.png\"><img src=\"https://github.com/smartcat-labs/berserker/raw/dev/images/architecture.png\" alt=\"Architecture\" /></a></p><p>Berserker is designed as command line tool, but having modular architecture makes it easy to use it as Java library as well.</p><h3>Berserker Commons</h3><p><a href=\"https://github.com/smartcat-labs/berserker/blob/dev/berserker-commons\">Berserker Commons</a> holds interface for core and configuration and it provides signature all the modules need to confront to be able to work together.</p><h3>Berserker Core</h3><p><a href=\"https://github.com/smartcat-labs/berserker/blob/dev/berserker-core\">Berserker Core</a> contains load generator implementation, and common implementations of data source, rate generator and worker.</p><h3>Berserker Runner</h3><p><a href=\"https://github.com/smartcat-labs/berserker/blob/dev/berserker-runner\">Berserker Runner</a> represents runnable jar where desired data source, rate generator and worker can be specified within YAML configuration.\nFollowing section illustrates YAML configuration example.</p><div class=\"highlight highlight-source-yaml\"><pre>load-generator-configuration:\n  data-source-configuration-name: Ranger\n  rate-generator-configuration-name: default\n  worker-configuration-name: Cassandra\n  metrics-reporter-configuration-name: JMX\n  thread-count: 10\n  queue-capacity: 100000\ndata-source-configuration:\n  values:\n    id: uuid()\n    firstName: random(['Peter', 'Mike', 'Steven', 'Joshua', 'John', 'Brandon'])\n    lastName: random(['Smith', 'Johnson', 'Williams', 'Davis', 'Jackson', 'White', 'Lewis', 'Clark'])\n    age: random(20..45)\n    email: string('{}@domain.com', randomLengthString(5))\n    statement:\n      consistencyLevel: ONE\n      query: string(\"INSERT INTO person (id, first_name, last_name, age, email) VALUES ({}, '{}', '{}', {}, '{}');\", $id, $firstName, $lastName, $age, $email)\n  output: $statement\nrate-generator-configuration:\n  rates:\n    r: 1000\n  output: $r\nworker-configuration:\n  connection-points: 0.0.0.0:32770\n  keyspace: my_keyspace\n  async: false\n  bootstrap-commands:\n    - \"CREATE KEYSPACE IF NOT EXISTS my_keyspace WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1};\"\n    - USE my_keyspace;\n    - CREATE TABLE IF NOT EXISTS person (id uuid, first_name text, last_name text, age int, email text, primary key (id));\nmetrics-reporter-configuration:\n  domain: berserker\n  filter:</pre></div><p>Main part of configuration is <code>load-generator-configuration</code> where concrete modules which will be used for data source, rate generator and worker need to be specified. After <code>load-generator-configuration</code> section, there should be exactly one section for data source, rate generator and worker.\nEach section is allowed to contain module specific configuration as configuration interpretation will be done by module itself.\nIn order for berserker-runner to be able to find particular module, each module jar must be in classpath.</p><h4>Rate generator configuration</h4><p>Documentation on rate generator configuration can be found <a href=\"https://github.com/smartcat-labs/berserker/blob/dev/rate-generator-configuration.md\">here</a>.</p><h3>Modules</h3><p>List of existing modules:</p><h4>Berserker Ranger</h4><p><a href=\"https://github.com/smartcat-labs/berserker/blob/dev/berserker-ranger\">Berserker Ranger</a> is Ranger data source implementation.</p><h4>Berserker Kafka</h4><p><a href=\"https://github.com/smartcat-labs/berserker/blob/dev/berserker-kafka\">Berserker Kafka</a> is worker implementation which sends messages to Kafka cluster.</p><h4>Berserker Cassandra</h4><p><a href=\"https://github.com/smartcat-labs/berserker/blob/dev/berserker-cassandra\">Berserker Cassandra</a> is worker implementation which executes CQL statements on Cassandra cluster.</p><h4>Berserker HTTP</h4><p><a href=\"https://github.com/smartcat-labs/berserker/blob/dev/berserker-http\">Berserker HTTP</a> is worker implementation which sends HTTP request on configured endpoint.</p><h4>Berserker RabbitMQ</h4><p><a href=\"https://github.com/smartcat-labs/berserker/blob/dev/berserker-rabbitmq\">Berserker RabbitMQ</a> is worker implementation which sends AMQP messages to RabbitMQ.</p><h4>Berserker MQTT</h4><p><a href=\"https://github.com/smartcat-labs/berserker/blob/dev/berserker-mqtt\">Berserker MQTT</a> is worker implementation which publishes messages to MQTT broker.</p><h3>Usage</h3><p>Berserker can be used either as a library or as a stand-alone command line tool.</p><h4>Library usage</h4><p>Artifact can be fetched from bintray.</p><p>Add following <code>repository</code> element to your <code>&lt;repositories&gt;</code> section in <code>pom.xml</code>:</p><div class=\"highlight highlight-text-xml\"><pre>&lt;repository&gt;\n  &lt;id&gt;bintray-smartcat-labs-maven&lt;/id&gt;\n  &lt;name&gt;bintray&lt;/name&gt;\n  &lt;url&gt;https://dl.bintray.com/smartcat-labs/maven&lt;/url&gt;\n&lt;/repository&gt;</pre></div><p>Add the <code>dependency</code> element to your <code>&lt;dependencies&gt;</code> section in <code>pom.xml</code> depending which <code>artifact</code> and <code>version</code> you need:</p><div class=\"highlight highlight-text-xml\"><pre>&lt;dependency&gt;\n  &lt;groupId&gt;io.smartcat&lt;/groupId&gt;\n  &lt;artifactId&gt;artifact&lt;/artifactId&gt;\n  &lt;version&gt;version&lt;/version&gt;\n&lt;/dependency&gt;</pre></div><h4>Command line tool usage</h4><ul><li>Download latest <a href=\"https://bintray.com/smartcat-labs/maven/berserker\" rel=\"nofollow\">Berserker Runner</a> version.</li>\n<li>Create config file (example can be found <a href=\"https://github.com/smartcat-labs/berserker/blob/dev/berserker-runner/src/example/resources/ranger-cassandra.yml\">here</a>).</li>\n<li>Run following command: <code>java -jar berserker-runner-&lt;version&gt;.jar -c &lt;path_to_config_file&gt;</code></li>\n<li>If you need to specify logging options, you can run berserker this way: <code>java -jar -Dlogback.configurationFile=&lt;path to logback.xml&gt; berserker-runner-&lt;version&gt;.jar -c &lt;path_to_config_file&gt;</code></li>\n</ul>","id":"bbcb1335-9a12-500a-a6e6-ab15920ef1b1","title":"smartcat-labs/berserker","origin_url":"https://github.com/smartcat-labs/berserker","url":"https://github.com/smartcat-labs/berserker","wallabag_created_at":"2018-05-17T18:23:25+00:00","published_at":null,"published_by":"['']","reading_time":3,"domain_name":"github.com","preview_picture":"https://opengraph.githubassets.com/0349248a3cff661557423583e7a24bbd535f2d52c22df015505774be4f3bbed7/smartcat-labs/berserker","tags":["cassandra","github","testing"],"description":"Load generator with modular architecture.\n Berserker is designed to be modular from beginning as illustrated on the following diagram.Rate generator controls the rate at which load generator operates,..."},"relatedArticles":[{"content":"<div data-pjax-replace=\"\" id=\"js-flash-container\"><div class=\"flash flash-full {{ className }} px-2\"><p>{{ message }}</p></div>\n</div><div class=\"application-main\" data-commit-hovercards-enabled=\"\" data-discussion-hovercards-enabled=\"\" data-issue-and-pr-hovercards-enabled=\"\"><main id=\"js-repo-pjax-container\" data-pjax-container=\"\"><div id=\"repository-container-header\" class=\"pt-3 hide-full-screen c3\" data-pjax-replace=\"\"><div class=\"d-flex mb-3 px-3 px-md-4 px-lg-5\"><p> / <strong itemprop=\"name\" class=\"mr-2 flex-self-stretch\"><a data-pjax=\"#repo-content-pjax-container\" href=\"https://github.com/apache/cassandra-harry\">cassandra-harry</a></strong> Public</p><ul class=\"pagehead-actions flex-shrink-0 d-none d-md-inline c1\"><li><a href=\"https://github.com/login?return_to=%2Fapache%2Fcassandra-harry\" rel=\"nofollow\" data-hydro-click=\"{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;notification subscription menu watch&quot;,&quot;repository_id&quot;:null,&quot;auth_type&quot;:&quot;LOG_IN&quot;,&quot;originating_url&quot;:&quot;https://github.com/apache/cassandra-harry&quot;,&quot;user_id&quot;:null}}\" data-hydro-click-hmac=\"9cf17cf30bb042224fd5877004d34f4e99e95f6488041ba1ea9a11a0bab36f47\" aria-label=\"You must be signed in to change notification settings\" data-view-component=\"true\" class=\"tooltipped tooltipped-s btn-sm btn\">Notifications</a></li>\n<li><a href=\"https://github.com/login?return_to=%2Fapache%2Fcassandra-harry\" rel=\"nofollow\" data-hydro-click=\"{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;repo details fork button&quot;,&quot;repository_id&quot;:292627306,&quot;auth_type&quot;:&quot;LOG_IN&quot;,&quot;originating_url&quot;:&quot;https://github.com/apache/cassandra-harry&quot;,&quot;user_id&quot;:null}}\" data-hydro-click-hmac=\"16cc71ae0543724bd3934f99a05d0a8a4c0dad8342599c07e6c15e6e968b5552\" aria-label=\"You must be signed in to fork a repository\" data-view-component=\"true\" class=\"tooltipped tooltipped-s btn-sm btn\">Fork 12</a></li>\n<li>\n<p><a href=\"https://github.com/login?return_to=%2Fapache%2Fcassandra-harry\" rel=\"nofollow\" data-hydro-click=\"{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;star button&quot;,&quot;repository_id&quot;:292627306,&quot;auth_type&quot;:&quot;LOG_IN&quot;,&quot;originating_url&quot;:&quot;https://github.com/apache/cassandra-harry&quot;,&quot;user_id&quot;:null}}\" data-hydro-click-hmac=\"f371aced4cf7d947b7473514455df8a59812332fa68e0591cfbcbabb5876773e\" aria-label=\"You must be signed in to star a repository\" data-view-component=\"true\" class=\"tooltipped tooltipped-s btn-sm btn BtnGroup-item\"> Star 43</a> </p>\n</li>\n</ul></div><div class=\"d-block d-md-none mb-2 px-3 px-md-4 px-lg-5\" id=\"responsive-meta-container\" data-pjax-replace=\"\"><p class=\"f4 mb-3\">Apache Cassandra - Harry</p><p><a title=\"https://cassandra.apache.org/\" role=\"link\" target=\"_blank\" class=\"text-bold\" rel=\"noopener noreferrer\" href=\"https://cassandra.apache.org/\">cassandra.apache.org/</a></p><h3 class=\"sr-only\">License</h3><p><a href=\"https://github.com/apache/cassandra-harry/blob/trunk/LICENSE.txt\" class=\"Link--muted\" data-analytics-event=\"{&quot;category&quot;:&quot;Repository Overview&quot;,&quot;action&quot;:&quot;click&quot;,&quot;label&quot;:&quot;location:sidebar;file:license&quot;}\"> Apache-2.0 license</a></p><p><a class=\"Link--secondary no-underline mr-3\" href=\"https://github.com/apache/cassandra-harry/stargazers\"> 43 stars</a> <a class=\"Link--secondary no-underline\" href=\"https://github.com/apache/cassandra-harry/network/members\"> 12 forks</a></p><div class=\"d-flex\"><p><a href=\"https://github.com/login?return_to=%2Fapache%2Fcassandra-harry\" rel=\"nofollow\" data-hydro-click=\"{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;star button&quot;,&quot;repository_id&quot;:292627306,&quot;auth_type&quot;:&quot;LOG_IN&quot;,&quot;originating_url&quot;:&quot;https://github.com/apache/cassandra-harry&quot;,&quot;user_id&quot;:null}}\" data-hydro-click-hmac=\"f371aced4cf7d947b7473514455df8a59812332fa68e0591cfbcbabb5876773e\" aria-label=\"You must be signed in to star a repository\" data-view-component=\"true\" class=\"tooltipped tooltipped-s btn-sm btn btn-block BtnGroup-item\"> Star</a> </p><p><a href=\"https://github.com/login?return_to=%2Fapache%2Fcassandra-harry\" rel=\"nofollow\" data-hydro-click=\"{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;notification subscription menu watch&quot;,&quot;repository_id&quot;:null,&quot;auth_type&quot;:&quot;LOG_IN&quot;,&quot;originating_url&quot;:&quot;https://github.com/apache/cassandra-harry&quot;,&quot;user_id&quot;:null}}\" data-hydro-click-hmac=\"9cf17cf30bb042224fd5877004d34f4e99e95f6488041ba1ea9a11a0bab36f47\" aria-label=\"You must be signed in to change notification settings\" data-view-component=\"true\" class=\"tooltipped tooltipped-s btn-sm btn btn-block\">Notifications</a></p></div></div></div>\n</main></div>\n<footer class=\"footer width-full container-xl p-responsive\" role=\"contentinfo\"><div class=\"position-relative d-flex flex-items-center pb-2 f6 color-fg-muted border-top color-border-muted flex-column-reverse flex-lg-row flex-wrap flex-lg-nowrap mt-6 pt-6\"><ul class=\"list-style-none d-flex flex-wrap col-0 col-lg-2 flex-justify-start flex-lg-justify-between mb-2 mb-lg-0\"><li class=\"mt-2 mt-lg-0 d-flex flex-items-center\"> © 2022 GitHub, Inc.</li>\n</ul></div>\n</footer><p> You can’t perform that action at this time.</p>\n<p> You signed in with another tab or window. <a href=\"\">Reload</a> to refresh your session. You signed out in another tab or window. <a href=\"\">Reload</a> to refresh your session.</p>\n<details class=\"details-reset details-overlay details-overlay-dark lh-default color-fg-default hx_rsm\" open=\"open\">\n\n</details>","id":"166bfd43-cfec-506b-be68-f384b93820b4","title":"GitHub - apache/cassandra-harry: Apache Cassandra - Harry","origin_url":"https://github.com/apache/cassandra-harry","url":"https://github.com/apache/cassandra-harry","wallabag_created_at":"2022-06-08T20:37:16+00:00","published_at":null,"published_by":"['apache']","reading_time":null,"domain_name":"github.com","preview_picture":"https://opengraph.githubassets.com/aa15162e4aac1bfa5fbd58f2757de131eaa602ad2bc71025321e6eeb66ff4553/apache/cassandra-harry","tags":["cassandra","testing"],"description":"{{ message }}\n / cassandra-harry PublicNotifications\nFork 12\n\n Star 43 \n\nApache Cassandra - Harrycassandra.apache.org/License Apache-2.0 license 43 stars  12 forks Star Notifications\n\n © 2022 GitHub, ..."},{"content":"<div class=\"flash flash-full {{ className }} px-2\" data-pjax-replace=\"\" id=\"js-flash-container\"><p>{{ message }}</p></div>\n<div class=\"application-main\" data-commit-hovercards-enabled=\"\" data-discussion-hovercards-enabled=\"\" data-issue-and-pr-hovercards-enabled=\"\"><main id=\"js-repo-pjax-container\" data-pjax-container=\"\"><div id=\"repository-container-header\" class=\"pt-3 hide-full-screen c3\" data-pjax-replace=\"\"><div class=\"d-block d-md-none mb-2 px-3 px-md-4 px-lg-5\" id=\"responsive-meta-container\" data-pjax-replace=\"\"><p class=\"f4 mb-3\">Apache cassandra diff</p><p><a title=\"https://cassandra.apache.org/\" role=\"link\" target=\"_blank\" class=\"text-bold\" rel=\"noopener noreferrer\" href=\"https://cassandra.apache.org/\">cassandra.apache.org/</a></p><h3 class=\"sr-only\">License</h3><p><a href=\"https://github.com/apache/cassandra-diff/blob/trunk/LICENSE.txt\" class=\"Link--muted\" data-analytics-event=\"{&quot;category&quot;:&quot;Repository Overview&quot;,&quot;action&quot;:&quot;click&quot;,&quot;label&quot;:&quot;location:sidebar;file:license&quot;}\">Apache-2.0 license</a></p><p><a class=\"Link--secondary no-underline mr-3\" href=\"https://github.com/apache/cassandra-diff/stargazers\">10 stars</a> <a class=\"Link--secondary no-underline\" href=\"https://github.com/apache/cassandra-diff/network/members\">16 forks</a></p></div></div>\n</main></div>\n<footer class=\"footer width-full container-xl p-responsive\" role=\"contentinfo\"><div class=\"position-relative d-flex flex-items-center pb-2 f6 color-fg-muted border-top color-border-muted flex-column-reverse flex-lg-row flex-wrap flex-lg-nowrap mt-6 pt-6\"><ul class=\"list-style-none d-flex flex-wrap col-0 col-lg-2 flex-justify-start flex-lg-justify-between mb-2 mb-lg-0\"><li class=\"mt-2 mt-lg-0 d-flex flex-items-center\">© 2022 GitHub, Inc.</li>\n</ul></div>\n</footer><p>You can’t perform that action at this time.</p>\n<p>You signed in with another tab or window. <a href=\"\">Reload</a> to refresh your session. You signed out in another tab or window. <a href=\"\">Reload</a> to refresh your session.</p>\n<details class=\"details-reset details-overlay details-overlay-dark lh-default color-fg-default hx_rsm\" open=\"open\"></details>","id":"d29b900a-7c3e-537e-a25e-6c8caff38e03","title":"GitHub - apache/cassandra-diff: Apache cassandra diff","origin_url":"https://github.com/apache/cassandra-diff","url":"https://github.com/apache/cassandra-diff","wallabag_created_at":"2022-06-08T20:37:07+00:00","published_at":null,"published_by":"['']","reading_time":null,"domain_name":"github.com","preview_picture":"https://opengraph.githubassets.com/e7a10c615cc491e34c4e3f952c02c227c9b02a49ab4ccf2ebd3bc5832f285203/apache/cassandra-diff","tags":["cassandra","testing"],"description":"{{ message }}\nApache cassandra diffcassandra.apache.org/LicenseApache-2.0 license10 stars 16 forks\n\n© 2022 GitHub, Inc.\n\nYou can’t perform that action at this time.\nYou signed in with another tab or w..."},{"content":"<div data-pjax-replace=\"\" id=\"js-flash-container\"><div class=\"flash flash-full {{ className }} px-2\"><p>{{ message }}</p></div>\n</div><div class=\"application-main\" data-commit-hovercards-enabled=\"\" data-discussion-hovercards-enabled=\"\" data-issue-and-pr-hovercards-enabled=\"\"><main id=\"js-repo-pjax-container\" data-pjax-container=\"\"><div id=\"repository-container-header\" class=\"pt-3 hide-full-screen c3\" data-pjax-replace=\"\"><div class=\"d-flex mb-3 px-3 px-md-4 px-lg-5\"><p> / <strong itemprop=\"name\" class=\"mr-2 flex-self-stretch\"><a data-pjax=\"#repo-content-pjax-container\" href=\"https://github.com/datastax/adelphi\">adelphi</a></strong> Public</p><ul class=\"pagehead-actions flex-shrink-0 d-none d-md-inline c1\"><li><a href=\"https://github.com/login?return_to=%2Fdatastax%2Fadelphi\" rel=\"nofollow\" data-hydro-click=\"{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;notification subscription menu watch&quot;,&quot;repository_id&quot;:null,&quot;auth_type&quot;:&quot;LOG_IN&quot;,&quot;originating_url&quot;:&quot;https://github.com/datastax/adelphi&quot;,&quot;user_id&quot;:null}}\" data-hydro-click-hmac=\"dd7eb365e4b5d3f98a22bdd8d18a4af0fbd166a0491e1f620c51d20d647aec28\" aria-label=\"You must be signed in to change notification settings\" data-view-component=\"true\" class=\"tooltipped tooltipped-s btn-sm btn\">Notifications</a></li>\n<li><a href=\"https://github.com/login?return_to=%2Fdatastax%2Fadelphi\" rel=\"nofollow\" data-hydro-click=\"{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;repo details fork button&quot;,&quot;repository_id&quot;:280185818,&quot;auth_type&quot;:&quot;LOG_IN&quot;,&quot;originating_url&quot;:&quot;https://github.com/datastax/adelphi&quot;,&quot;user_id&quot;:null}}\" data-hydro-click-hmac=\"1997e3a5189659d5f9c924425df984a1798c6158f289de62ec3cf960385f554d\" aria-label=\"You must be signed in to fork a repository\" data-view-component=\"true\" class=\"tooltipped tooltipped-s btn-sm btn\">Fork 4</a></li>\n<li>\n<p><a href=\"https://github.com/login?return_to=%2Fdatastax%2Fadelphi\" rel=\"nofollow\" data-hydro-click=\"{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;star button&quot;,&quot;repository_id&quot;:280185818,&quot;auth_type&quot;:&quot;LOG_IN&quot;,&quot;originating_url&quot;:&quot;https://github.com/datastax/adelphi&quot;,&quot;user_id&quot;:null}}\" data-hydro-click-hmac=\"f054bc7eba043e2fe1b97fb786319ed96ea23960ae6311a7994628481c32ae93\" aria-label=\"You must be signed in to star a repository\" data-view-component=\"true\" class=\"tooltipped tooltipped-s btn-sm btn BtnGroup-item\"> Star 9</a> </p>\n</li>\n</ul></div><div class=\"d-block d-md-none mb-2 px-3 px-md-4 px-lg-5\" id=\"responsive-meta-container\" data-pjax-replace=\"\"><p class=\"f4 mb-3\">Automation tool for testing C* OSS that assembles cassandra-diff, nosqlbench, fqltool</p><h3 class=\"sr-only\">License</h3><p><a href=\"https://github.com/datastax/adelphi/blob/master/LICENSE.txt\" class=\"Link--muted\" data-analytics-event=\"{&quot;category&quot;:&quot;Repository Overview&quot;,&quot;action&quot;:&quot;click&quot;,&quot;label&quot;:&quot;location:sidebar;file:license&quot;}\"> Apache-2.0 license</a></p><p><a class=\"Link--secondary no-underline mr-3\" href=\"https://github.com/datastax/adelphi/stargazers\"> 9 stars</a> <a class=\"Link--secondary no-underline\" href=\"https://github.com/datastax/adelphi/network/members\"> 4 forks</a></p><div class=\"d-flex\"><p><a href=\"https://github.com/login?return_to=%2Fdatastax%2Fadelphi\" rel=\"nofollow\" data-hydro-click=\"{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;star button&quot;,&quot;repository_id&quot;:280185818,&quot;auth_type&quot;:&quot;LOG_IN&quot;,&quot;originating_url&quot;:&quot;https://github.com/datastax/adelphi&quot;,&quot;user_id&quot;:null}}\" data-hydro-click-hmac=\"f054bc7eba043e2fe1b97fb786319ed96ea23960ae6311a7994628481c32ae93\" aria-label=\"You must be signed in to star a repository\" data-view-component=\"true\" class=\"tooltipped tooltipped-s btn-sm btn btn-block BtnGroup-item\"> Star</a> </p><p><a href=\"https://github.com/login?return_to=%2Fdatastax%2Fadelphi\" rel=\"nofollow\" data-hydro-click=\"{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;notification subscription menu watch&quot;,&quot;repository_id&quot;:null,&quot;auth_type&quot;:&quot;LOG_IN&quot;,&quot;originating_url&quot;:&quot;https://github.com/datastax/adelphi&quot;,&quot;user_id&quot;:null}}\" data-hydro-click-hmac=\"dd7eb365e4b5d3f98a22bdd8d18a4af0fbd166a0491e1f620c51d20d647aec28\" aria-label=\"You must be signed in to change notification settings\" data-view-component=\"true\" class=\"tooltipped tooltipped-s btn-sm btn btn-block\">Notifications</a></p></div></div></div>\n</main></div>\n<footer class=\"footer width-full container-xl p-responsive\" role=\"contentinfo\"><div class=\"position-relative d-flex flex-items-center pb-2 f6 color-fg-muted border-top color-border-muted flex-column-reverse flex-lg-row flex-wrap flex-lg-nowrap mt-6 pt-6\"><ul class=\"list-style-none d-flex flex-wrap col-0 col-lg-2 flex-justify-start flex-lg-justify-between mb-2 mb-lg-0\"><li class=\"mt-2 mt-lg-0 d-flex flex-items-center\"> © 2022 GitHub, Inc.</li>\n</ul></div>\n</footer><p> You can’t perform that action at this time.</p>\n<p> You signed in with another tab or window. <a href=\"\">Reload</a> to refresh your session. You signed out in another tab or window. <a href=\"\">Reload</a> to refresh your session.</p>\n<details class=\"details-reset details-overlay details-overlay-dark lh-default color-fg-default hx_rsm\" open=\"open\">\n\n</details>","id":"75fb8bf0-c48c-58d3-b5ef-b60dc7508eb1","title":"GitHub - datastax/adelphi: Automation tool for testing C* OSS that assembles cassandra-diff, nosqlbench, fqltool","origin_url":"https://github.com/datastax/adelphi","url":"https://github.com/datastax/adelphi","wallabag_created_at":"2022-06-08T20:36:15+00:00","published_at":null,"published_by":"['datastax']","reading_time":null,"domain_name":"github.com","preview_picture":"https://opengraph.githubassets.com/afe20d0322f42c980557122f254ed0db1a89239e8a1e4130618ed630ed786ddc/datastax-archive/adelphi","tags":["stress","cassandra","cassandra.stress","testing"],"description":"{{ message }}\n / adelphi PublicNotifications\nFork 4\n\n Star 9 \n\nAutomation tool for testing C* OSS that assembles cassandra-diff, nosqlbench, fqltoolLicense Apache-2.0 license 9 stars  4 forks Star Not..."},{"content":"<article class=\"markdown-body entry-content\" itemprop=\"text\">\n<p>This is a sample code of utilizing <a href=\"https://gatling.io/\" rel=\"nofollow\">Gatling</a> testing framework for stress testing with DSE</p>\n<h3><a id=\"user-content-pre-requisites\" class=\"anchor\" aria-hidden=\"true\" href=\"#pre-requisites\"></a>Pre-requisites</h3>\n<p>Note: At the moment, the latest version of Gatling framework is 2.3.1. However, the CQL plugin 0.0.7 is not compatible with Gatling 2.3.1 yet.</p>\n<ol><li>Gatling high charts bundle version 2.2.5:</li>\n</ol><ul><li><a href=\"https://repo1.maven.org/maven2/io/gatling/highcharts/gatling-charts-highcharts-bundle/2.2.5/\" rel=\"nofollow\">https://repo1.maven.org/maven2/io/gatling/highcharts/gatling-charts-highcharts-bundle/2.2.5/</a></li>\n</ul><ol start=\"2\"><li>Gatling CQL plugin v0.0.7 (latest version as of writing)</li>\n</ol><p><strong>[NOTES]</strong> - as of April 10, 2018, Gatling CQL plugin has released version 0.0.8 which works with the latest Gatling framework 2.3.1. Please feel free to download these latest versions for your test. Please also be aware that Gatling 2.3.1 requires scala 2.1.2 and make sure your scala version is upgraded first.</p>\n<h3><a id=\"user-content-notes-about-the-example-simulation-scenario\" class=\"anchor\" aria-hidden=\"true\" href=\"#notes-about-the-example-simulation-scenario\"></a>Notes about the Example Simulation Scenario</h3>\n<p>The simulation scenario (MyTestSimu.scala) as included in this example simulates a mixed read/write workload. The core steps of the scenario are summarized below and you can follow the same steps when creating your own scenario:</p>\n<ol><li>Set up connection to Cassandra/DSE cluster with proper properties, such as \"contact points\", \"load balancing policy\", etc.</li>\n<li>Create the application keyspace and table schema</li>\n<li>Define the (random) value generator for table columns based on their types</li>\n<li>Define the Read/Write statements to be used in the simulation, including the Consistency Level associated with the statements</li>\n<li>Set up the user simulation behavior for Read and Write. The key parts include:</li>\n</ol><ul><li>How many concurrent users (can be constant or some variance) to be simulated per second.</li>\n<li>How long does the simulation executes</li>\n</ul><h3><a id=\"user-content-procedure\" class=\"anchor\" aria-hidden=\"true\" href=\"#procedure\"></a>Procedure</h3>\n<ol><li>Set up Gatling framework and the CQL plug-in (just unzip, as per description found <a href=\"https://github.com/gatling-cql/GatlingCql\">here</a>)</li>\n<li>Download the MyTestSimu.scala file and put it under folder &lt;GATLING_HOME&gt;/user-files/simulations/</li>\n<li>Execute the Gatling simulation (stress-testing) scenario by running command: &lt;GATLING_HOME&gt;/bin/gatling.sh. Follow the instructions on the command-line output.</li>\n</ol><p>NOTE: The simulation scenario (MyTestSimu.scala) is tested against a DSE cluster (version 5.1.6) with UserName/Password authentication. Please adjust accordingly for your case.</p>\n<hr /><p>An example is as below. Simulation number 1 is the Cassandra stres-testing scenario as defined by this example.</p>\n<pre>$ bin/gatling.sh\nGATLING_HOME is set to /home/automaton/gatling-charts-highcharts-bundle-2.2.5\nChoose a simulation number:\n     [0] cassandra.CassandraSimulation\n     [1] cassandra.MyTestSimu\n     [2] computerdatabase.BasicSimulation\n     [3] computerdatabase.advanced.AdvancedSimulationStep01\n     [4] computerdatabase.advanced.AdvancedSimulationStep02\n     [5] computerdatabase.advanced.AdvancedSimulationStep03\n     [6] computerdatabase.advanced.AdvancedSimulationStep04\n     [7] computerdatabase.advanced.AdvancedSimulationStep05\n1\nSelect simulation id (default is 'mytestsimu'). Accepted characters are a-z, A-Z, 0-9, - and _\nSelect run description (optional)\nSimulation cassandra.MyTestSimu started...\n================================================================================\n2018-04-04 15:33:43                                           5s elapsed\n---- Requests ------------------------------------------------------------------\n&gt; Global                                                   (OK=232    KO=0     )\n&gt; upsertStmt                                               (OK=93     KO=0     )\n&gt; readStmt                                                 (OK=139    KO=0     )\n---- Read Workload Scenario ----------------------------------------------------\n[#                                                                         ]  1%\n          waiting: 8861   / active: 0      / done:139\n---- Write Workload Scenario ---------------------------------------------------\n[                                                                          ]  0%\n          waiting: 20907  / active: 0      / done:93\n================================================================================\n... ...\n================================================================================\n2018-04-04 15:43:39                                         600s elapsed\n---- Requests ------------------------------------------------------------------\n&gt; Global                                                   (OK=30000  KO=0     )\n&gt; upsertStmt                                               (OK=21000  KO=0     )\n&gt; readStmt                                                 (OK=9000   KO=0     )\n---- Read Workload Scenario ----------------------------------------------------\n[##########################################################################]100%\n          waiting: 0      / active: 0      / done:9000\n---- Write Workload Scenario ---------------------------------------------------\n[##########################################################################]100%\n          waiting: 0      / active: 0      / done:21000\n================================================================================\nSimulation cassandra.MyTestSimu completed in 600 seconds\nParsing log file(s)...\nParsing log file(s) done\nGenerating reports...\n================================================================================\n---- Global Information --------------------------------------------------------\n&gt; request count                                      30000 (OK=30000  KO=0     )\n&gt; min response time                                      0 (OK=0      KO=-     )\n&gt; max response time                                    224 (OK=224    KO=-     )\n&gt; mean response time                                     2 (OK=2      KO=-     )\n&gt; std deviation                                          5 (OK=5      KO=-     )\n&gt; response time 50th percentile                          1 (OK=1      KO=-     )\n&gt; response time 75th percentile                          2 (OK=2      KO=-     )\n&gt; response time 95th percentile                          3 (OK=3      KO=-     )\n&gt; response time 99th percentile                          7 (OK=7      KO=-     )\n&gt; mean requests/sec                                     50 (OK=50     KO=-     )\n---- Response Time Distribution ------------------------------------------------\n&gt; t &lt; 800 ms                                         30000 (100%)\n&gt; 800 ms &lt; t &lt; 1200 ms                                   0 (  0%)\n&gt; t &gt; 1200 ms                                            0 (  0%)\n&gt; failed                                                 0 (  0%)\n================================================================================\nReports generated in 4s.\nPlease open the following file: /home/automaton/gatling-charts-highcharts-bundle-2.2.5/results/mytestsimu-1522856018600/index.html\n</pre>\n</article>","id":"22b64c72-6b88-5842-8e08-ebff60cc319b","title":"yabinmeng/cassgatling","origin_url":"https://github.com/yabinmeng/cassgatling","url":"https://github.com/yabinmeng/cassgatling","wallabag_created_at":"2018-11-14T17:34:32+00:00","published_at":null,"published_by":null,"reading_time":3,"domain_name":"github.com","preview_picture":"https://opengraph.githubassets.com/ba96401352e04a099abef2d795d350d978caf9070e2f7cf302b70025f16fcffd/yabinmeng/cassgatling","tags":["stress","cassandra","gatling","testing"],"description":"\nThis is a sample code of utilizing Gatling testing framework for stress testing with DSE\nPre-requisites\nNote: At the moment, the latest version of Gatling framework is 2.3.1. However, the CQL plugin ..."},{"content":"<article class=\"markdown-body entry-content\" itemprop=\"text\">\n<ul><li>I wanted to run some <code>cassandra-stress</code> testing on the three main cloud providers (Google, Amazon, and Microsoft) on similarly sized DataStax Enterprise clusters and see what the results would be</li>\n<li>Why did I want to do this? When running on a cluster of similarly-sized VMs, networking starts to come into play for replication, storage, and stronger consistency levels. This type of an exercise exposes the network so you can understand what you may have to contend with for a specific cloud provider versus another</li>\n<li>This is also a tutorial on some of the fun switches that you can use to tune your <code>cassandra-stress</code> test</li>\n<li>This is not a tutorial on how to deploy the VMs, if you want that information, please go over to another repo of mine as I repurposed it. It is 99% similar; I just didn't enable SSL and installed <code>dse-full</code>: <a href=\"https://github.com/justinbreese/dse-multi-cloud-demo\">https://github.com/justinbreese/dse-multi-cloud-demo</a></li>\n</ul><h2><a id=\"user-content-methodology\" class=\"anchor\" aria-hidden=\"true\" href=\"#methodology\"></a>Methodology</h2>\n<ul><li>Setup 4 VMs on each of the cloud providers; VM size was as close as possible with similar storage provisioned: i3.4xl, Standard_DS14_v2, and n1-highmem-16</li>\n<li>3 of the VMs will be running DataStax Enterprise as their own cluster; again each cloud is their own cluster</li>\n<li>The 4th VM runs DataStax OpsCenter and acts as a <code>cassandra-stress</code> client\n<a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/justinbreese/dse-cassandra-stress/blob/master/architecture.png?raw=true\"><img src=\"https://github.com/justinbreese/dse-cassandra-stress/raw/master/architecture.png?raw=true\" alt=\"Screenshot\" /></a></li>\n<li>Next, I ran this test on each of the clients 35 times: <code>cassandra-stress user profile=stress.yaml n=1000000 ops\\(insert=3,likelyquery1=1\\) cl=QUORUM -mode native cql3 user=cassandra password=datastax -node 104.196.140.126 -rate threads\\&gt;=121</code>\n<ul><li>I then captured the results into an Excel file</li>\n</ul></li>\n<li>Then I decided to really turn it up and do 1B operations; and it led to this test that was run once on each of the clients: <code>nohup cassandra-stress user profile=stress.yaml n=1000000000 ops\\(insert=3,likelyquery1=1\\) cl=QUORUM -mode native cql3 user=cassandra password=datastax -node 40.118.149.27 -rate threads=300 -log file=output.txt -errors ignore</code>\n<ul><li>Again, I captured the results in an Excel file</li>\n</ul></li>\n</ul><h2><a id=\"user-content-breakdown-the-switches\" class=\"anchor\" aria-hidden=\"true\" href=\"#breakdown-the-switches\"></a>Breakdown the switches!</h2>\n<p>I told you that this would be educational!</p>\n<h3><a id=\"user-content-first-test\" class=\"anchor\" aria-hidden=\"true\" href=\"#first-test\"></a>First test</h3>\n<p><code>cassandra-stress user profile=stress.yaml n=1000000 ops\\(insert=3,likelyquery1=1\\) cl=QUORUM -mode native cql3 user=cassandra password=datastax -node 104.196.140.126 -rate threads\\&gt;=121</code></p>\n<ul><li><code>profile=stress.yaml</code> --&gt; take a look at the one that I created in the root of this repo. I went to a colleague's website and was able to build it in a few minutes (source below). Do this to create the actual data model that you want to use in production!</li>\n<li><code>n=1000000</code> --&gt; the amount of times that you want to run operations</li>\n<li><code>ops\\(insert=3,likelyquery1=1\\)</code> --&gt; the ratio of writes:reads that you want done for your test. This is a 3:1 ratio. You can be specific about the reads that you want done. In <code>stress.yaml</code>, towards the bottom, there is a query called <code>likelyquery</code> that I want to run for my reads. You can customize this to read whatever query you prefer; super useful!</li>\n<li><code>cl=QUORUM</code> --&gt; consistency level. I see way too many stress tests done just at a consistency level of <code>CL=ONE</code>. The reality is that most don't run with a <code>CL=ONE</code> when they're in production; so why would they test against it now. Run your test against the consistency level that you want to run in production!</li>\n<li><code>-mode native cql3 user=cassandra password=datastax</code> --&gt; you need the client to be able to access DataStax Enterprise, so ensure it has the correct username and password to do so</li>\n<li><code>-node 104.196.140.126</code> --&gt; as I am running on a client, I need to be able to connect to the cluster. This IP address was of one of the seed nodes for the cluster that I was targeting. Once I point it towards one node, the client will become aware of all of the other nodes via gossip.</li>\n<li><code>-rate threads\\&gt;=121</code> --&gt; this runs the test at thread levels that are greater than or equal to 121. You can run at less than that, but I wanted to run at realistic levels.\n<ul><li>A great first test is to run at <code>-rate auto</code> which will will start at a single digit thread count and work its way up as high as it can go. This is great for understanding what is going on so you can understand the relationship for latency, operations/second, threadcount, etc.</li>\n</ul></li>\n</ul><h2><a id=\"user-content-second-test\" class=\"anchor\" aria-hidden=\"true\" href=\"#second-test\"></a>Second test</h2>\n<p>I am not going to go over the flags/arguments that I went over in the previous example. Instead, I'll go over the new ones or changes.</p>\n<p><code>nohup cassandra-stress user profile=stress.yaml n=1000000000 ops\\(insert=3,likelyquery1=1\\) cl=QUORUM -mode native cql3 user=cassandra password=datastax -node 40.118.149.27 -rate threads=300 -log file=output.txt -errors ignore</code></p>\n<ul><li><code>nohup</code> --&gt; I nohup'd because I wanted this to run as its own process. The advantage here is that it will run after I exit the session, computer goes to sleep, etc.</li>\n<li><code>n=1000000000</code> --&gt; increased the ops to 1B</li>\n<li><code>-rate threads=300</code> --&gt; set the thread count to an even 300. This is generally a point at which we start to see saturation, contention, etc.; so I wanted to stay in that range for an extended period of time</li>\n<li><code>-log file=output.txt</code> --&gt; as this would be a long running test, I wanted to be able to save the output all into a file that way I could <code>SCP</code> it back to my laptop for analysis in Excel. Otherwise it will just print to the screen; and after 1B transactions, that gets messy!</li>\n<li><code>-errors ignore</code> --&gt; after you run 1B transactions, you will get errors eventually. Cassandra handles them just fine, but you don't want it to stop the test. Do this for your tests! Otherwise, you could have your test stop half-way through; ask me how I know...</li>\n</ul><h2><a id=\"user-content-results\" class=\"anchor\" aria-hidden=\"true\" href=\"#results\"></a>Results</h2>\n<p>to be continued... maybe, if I can.</p>\n<ul><li>If you want to learn more about <code>cassandra-stress</code>, then look no further than the excellent work of my colleague: <a href=\"https://www.datastax.com/dev/blog/data-modeler\" rel=\"nofollow\">https://www.datastax.com/dev/blog/data-modeler</a></li>\n<li>The actual tool that builds out the <code>stress.yaml</code>: <a href=\"https://www.sestevez.com/sestevez/CassandraDataModeler/\" rel=\"nofollow\">https://www.sestevez.com/sestevez/CassandraDataModeler/</a></li>\n</ul>\n<p>Thanks for taking a look at this repo and let me know if you have any questions.</p>\n</article>","id":"c7ef4299-9aed-5814-830c-152a2c71eee3","title":"justinbreese/dse-cassandra-stress","origin_url":"https://github.com/justinbreese/dse-cassandra-stress","url":"https://github.com/justinbreese/dse-cassandra-stress","wallabag_created_at":"2018-11-13T20:12:27+00:00","published_at":null,"published_by":null,"reading_time":5,"domain_name":"github.com","preview_picture":"https://opengraph.githubassets.com/ad3b3ac83d6bdca681e5fa455a46e248f827c4ef3fed9166b05113d5ea996ee6/justinbreese/dse-cassandra-stress","tags":["stress","cassandra","dse","testing","aws","google.cloud","azure"],"description":"\nI wanted to run some cassandra-stress testing on the three main cloud providers (Google, Amazon, and Microsoft) on similarly sized DataStax Enterprise clusters and see what the results would be\nWhy d..."},{"content":"<p>Developing software is fun. Developing software that is well tested, where those tests run quickly is even more fun.</p><p>Stubbed Cassandra is an open source tool that enables you to test applications that use Cassandra in a quick, deterministic way.</p><p>It is especially aimed edge case testing such as read and write timeouts.</p><p>It acts as a real Cassandra instance and can be primed to respond with results or with exceptions like read timeouts. It does this by implementing the server side of the CQL binary protocol.</p><p>It is separated into two components:</p><ul><li><a href=\"http://scassandra-docs.readthedocs.org/en/latest/java/overview/\">Java Client</a>: Java client for Scassandra. A thin Java wrapper around Scassandra that allows Java projects to depend on Scassandra via maven dependency and have a programmatic interface for starting/stopping and priming.</li>\n  <li><a href=\"http://scassandra-docs.readthedocs.org/en/latest/standalone/overview/\">Scassandra Server</a>: Stubbed Scassandra server. Only go here if you’re insterested in running Stubbed Cassandra without a build tool such as maven or gradle. Implemented in Scala, can be run as a standalone server or depended on via the Java client. Doesn’t have an embedded Cassandra, is a standalone implementation of the server side of the Cassandra native protocol. You can prime the server to return rows, read timeout and write timeout via a REST API.</li>\n</ul><p>Scassandra, currently v1.1.0, is aimed at Java developers so most of the information is on the Java Client section of the website.  It also may be used as a standalone jar.</p><h3 id=\"release-v111\">Release v1.1.1</h3><ul><li><a href=\"https://github.com/scassandra/scassandra-server/issues/181\">#181</a> - Record ‘USE ' queries in activity log</li>\n</ul><h3 id=\"release-v110\">Release v1.1.0</h3><ul><li><a href=\"https://github.com/scassandra/scassandra-server/pull/171\">#171</a> - Protocol 3 and 4 support.  Migrate cql-antlr into tree as submodule.</li>\n</ul><h3 id=\"release-v1010\">Release v1.0.10</h3><ul><li><a href=\"https://github.com/scassandra/scassandra-server/pull/167\">#167</a> - Provide CORS support to Scassandra endpoints</li>\n</ul><h3 id=\"release-v109\">Release v1.0.9</h3><ul><li><a href=\"https://github.com/scassandra/scassandra-server/pull/157\">#157</a> - Share ActorSystem between Scassandra instances</li>\n</ul><h3 id=\"release-v108\">Release v1.0.8</h3><ul><li><a href=\"https://github.com/scassandra/scassandra-server/pull/155\">#155</a> - Add getters for thens in multi-prime requests</li>\n</ul><h3 id=\"release-v107\">Release v1.0.7</h3><ul><li><a href=\"https://github.com/scassandra/scassandra-server/pull/151\">#151</a> - Allow priming of config using config object</li>\n  <li><a href=\"https://github.com/scassandra/scassandra-server/pull/154\">#154</a> - Provide custom configuration for batch result</li>\n</ul><h3 id=\"release-v106\">Release v1.0.6</h3><ul><li><a href=\"https://github.com/scassandra/scassandra-server/pull/149\">#149</a> - Introduce alias for Then to avoid reserved word issues</li>\n  <li><a href=\"https://github.com/scassandra/scassandra-server/pull/150\">#150</a> - Handle invalid types with an informative error message</li>\n</ul><h3 id=\"release-v105\">Release v1.0.5</h3><ul><li><a href=\"https://github.com/scassandra/scassandra-server/pull/148\">#148</a> - Use shapeless 2</li>\n</ul><h3 id=\"release-v104\">Release v1.0.4</h3><ul><li><a href=\"https://github.com/scassandra/scassandra-server/pull/147\">#147</a> - Akka configuration fix</li>\n</ul><h3 id=\"release-v103\">Release v1.0.3</h3><ul><li><a href=\"https://github.com/scassandra/scassandra-server/pull/141\">#141</a> - Add ability to retrieve prepared multi primes</li>\n</ul><h3 id=\"release-v102\">Release v1.0.2</h3><ul><li><a href=\"https://github.com/scassandra/scassandra-server/pull/140\">#140</a> - Support for clearing prepared multi primes</li>\n</ul><h3 id=\"release-v101\">Release v1.0.1</h3><ul><li><a href=\"https://github.com/scassandra/scassandra-server/pull/139\">#139</a> - Delay support for batch statements</li>\n</ul><h3 id=\"release-v100\">Release v1.0.0</h3><ul><li>Multi prime API.</li>\n</ul><h3 id=\"release-v0110\">Release v0.11.0</h3><ul><li>Log better error message for timeout binding to ports</li>\n  <li><a href=\"https://github.com/scassandra/scassandra-server/issues/112\">#112</a> - Prime Result that closes connection</li>\n  <li><a href=\"https://github.com/scassandra/scassandra-server/pull/115\">#115</a> - Archive standalone jar</li>\n</ul><h3 id=\"release-v0100\">Release v0.10.0</h3><ul><li>Batch support</li>\n  <li>Ability to see currently connected clients and kill connections</li>\n</ul><h3 id=\"release-v091\">Release v0.9.1</h3><ul><li>Java 6 suppport for those still sadly using it</li>\n  <li>Verification for when a prepared statement is prepared</li>\n  <li>Fat jar support</li>\n  <li>Capturing of query parameters for non-prepared statements</li>\n</ul><h3 id=\"release-v080\">Release v0.8.0</h3><ul><li>Noving to a single build for server, client and tests.</li>\n</ul><h3 id=\"release-v070\">Release v0.7.0</h3><ul><li>Support for priming specific errors e.g the number of replicas responded rather than just that it wsa a read/write timeout</li>\n  <li>Removed support for version 1.* of the Java DataStax driver due to classpath issues (you can still use 2.* with Cassandra 1.2 and it will work)</li>\n</ul><h3 id=\"release-v060\">Release v0.6.0</h3><ul><li>Support for maps of any type</li>\n  <li>New method for priming types: CqlType (the ColumnTypes enum has been deprecated)</li>\n  <li>Prepared statement matcher now handles maps</li>\n</ul><h3 id=\"release-v050\">Release v0.5.0</h3><ul><li>Support for lists and sets of any type</li>\n  <li>Prepared statement matcher that handles matching the varialbe list correctly</li>\n</ul><h3 id=\"release-v041\">Release v0.4.1</h3><ul><li>[Feature #50] Support adding a fixed delay to both queries and prepared statements</li>\n  <li>[Feature #52] Cassandra 2.1 support</li>\n  <li>[Feature #53] JUnit matchers for queries and prepared statements</li>\n</ul><h3 id=\"release-v030\">Release v0.3.0</h3><ul><li>Text map maps support: varchar, ascii and text</li>\n  <li>Can use a queryPattern rather than a query for priming, making knowing the exact query the application will execute no longer necessary</li>\n  <li>[Bug #49] QueryPattern for prepared statements for error scenarios do not work</li>\n</ul><h3 id=\"release-v020\">Release v0.2.0</h3><ul><li>Lists and sets of the character types: varchar, ascii and text</li>\n  <li>JUnit rule for Java Client</li>\n</ul><h3 id=\"release-v01\">Release v0.1</h3><ul><li>Priming of queries with columns of all the primitive types (no suport for collections/custom tyes).</li>\n  <li>Priming of prepared statements. The variable (?s) types and response types can be any of the primitive types.</li>\n  <li>Retrieval of a list of all recorded queries.</li>\n  <li>Retrieval of a list of all the recorded executed prepared statements. If the prepared statement has been primed then the variable values are also visible.</li>\n</ul><h3 id=\"feature-backlog\">Feature backlog</h3><ul><li>User defined types</li>\n  <li>Batches</li>\n  <li>Retrieval of a list of all prepared statements even if they haven’t been executed.</li>\n  <li>Priming of tables rather than queries. Currently Scassandra does not parse the query and compares an executed query with all the primes query field. This would be very useful for priming the system keyspace as certain drivers expect the same thing to be in system.local but do slightly different queries to retireve it.</li>\n</ul><p>For feature requests and bug reports raise an issue at the <a href=\"https://github.com/scassandra/scassandra-server/issues\">Github issues page</a></p><p>Any questions ping me on twitter: @chbatey</p><ul><li>Christopher Batey (@chbatey)</li>\n  <li>Andrew Tolbert</li>\n  <li>Dogan Narinc</li>\n</ul>","id":"f25dfc52-d2f5-5804-8a88-de850ba485a3","title":"Stubbed Cassandra","origin_url":"http://www.scassandra.org/","url":"http://www.scassandra.org/","wallabag_created_at":"2018-10-08T20:04:55+00:00","published_at":null,"published_by":null,"reading_time":4,"domain_name":"www.scassandra.org","preview_picture":null,"tags":["cassandra","testing"],"description":"Developing software is fun. Developing software that is well tested, where those tests run quickly is even more fun.Stubbed Cassandra is an open source tool that enables you to test applications that ..."},{"content":"<p><strong>Support:</strong> <a href=\"https://gitter.im/intuit/wasabi?utm_source=badge&amp;utm_medium=badge&amp;utm_campaign=pr-badge&amp;utm_content=badge\" rel=\"nofollow\"><img src=\"https://camo.githubusercontent.com/13115004d1de8c8debb6d9636ed770ceb3cd44ea/68747470733a2f2f6261646765732e6769747465722e696d2f696e747569742f7761736162692e737667\" alt=\"Join the chat at https://gitter.im/intuit/wasabi\" data-canonical-src=\"https://badges.gitter.im/intuit/wasabi.svg\" /></a> <br /><strong>Documentation:</strong> <a href=\"https://intuit.github.io/wasabi/v1/guide/index.html\" rel=\"nofollow\">User Guide</a>, <a href=\"https://intuit.github.io/wasabi/v1/javadocs/latest/\" rel=\"nofollow\">JavaDocs</a>\n<br /><strong>A/B Testing Overview:</strong> <a href=\"https://www.youtube.com/watch?v=_HtvJwBPUqk&amp;feature=youtu.be\" rel=\"nofollow\"><img src=\"https://camo.githubusercontent.com/7d0321a6112c23f202f9852f1db1d4587db17d85/687474703a2f2f696d672e736869656c64732e696f2f62616467652f766964656f2d412532464225323054657374696e672532304f766572766965772d7265642e737667\" alt=\"A/B Testing Overview\" data-canonical-src=\"http://img.shields.io/badge/video-A%2FB%20Testing%20Overview-red.svg\" /></a> <a href=\"https://medium.com/blueprint-by-intuit/open-sourcing-wasabi-the-a-b-testing-platform-by-intuit-a8d5abc958d\" rel=\"nofollow\"><img src=\"https://camo.githubusercontent.com/31955dbe1b8474ed4a4ab59e38a26e05b0ac0622/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f626c6f672d4d6565742532305761736162692d627269676874677265656e2e737667\" alt=\"Blog Meet Wasabi\" data-canonical-src=\"https://img.shields.io/badge/blog-Meet%20Wasabi-brightgreen.svg\" /></a> <a href=\"https://medium.com/blueprint-by-intuit/the-architecture-behind-wasabi-an-open-source-a-b-testing-platform-b52430d3fd80\" rel=\"nofollow\"><img src=\"https://camo.githubusercontent.com/f1f2ee9250c9a93017c1c82c4dc7fa0013d61401/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f626c6f672d417263686974656374757265253230426568696e642532305761736162692d6f72616e67652e737667\" alt=\"Blog Architecture Behind Wasabi\" data-canonical-src=\"https://img.shields.io/badge/blog-Architecture%20Behind%20Wasabi-orange.svg\" /></a> <br /><strong>Continuous Integration:</strong> <a href=\"https://travis-ci.org/intuit/wasabi\" rel=\"nofollow\"><img src=\"https://camo.githubusercontent.com/c02cc709a1c51c0107101c3d1a96e28b7f10dd1c/68747470733a2f2f6170692e7472617669732d63692e6f72672f696e747569742f7761736162692e7376673f6272616e63683d646576656c6f70\" alt=\"Build Status\" data-canonical-src=\"https://api.travis-ci.org/intuit/wasabi.svg?branch=develop\" /></a>\n<a href=\"https://coveralls.io/github/intuit/wasabi?branch=develop\" rel=\"nofollow\"><img src=\"https://camo.githubusercontent.com/21a3f18f699685c7ac4db1f687158a9bcfe1470f/68747470733a2f2f636f766572616c6c732e696f2f7265706f732f6769746875622f696e747569742f7761736162692f62616467652e737667\" alt=\"Coverage Status\" data-canonical-src=\"https://coveralls.io/repos/github/intuit/wasabi/badge.svg\" /></a>\n<a href=\"https://maven-badges.herokuapp.com/maven-central/com.intuit.wasabi/wasabi\" rel=\"nofollow\"><img src=\"https://camo.githubusercontent.com/6da12cf851ba62b357771ca25a0e3561339330c5/68747470733a2f2f6d6176656e2d6261646765732e6865726f6b756170702e636f6d2f6d6176656e2d63656e7472616c2f636f6d2e696e747569742e7761736162692f7761736162692f62616467652e737667\" alt=\"Maven Central\" data-canonical-src=\"https://maven-badges.herokuapp.com/maven-central/com.intuit.wasabi/wasabi/badge.svg\" /></a> <br /><strong>License:</strong> <a href=\"http://www.apache.org/licenses/LICENSE-2.0\" rel=\"nofollow\"><img src=\"https://camo.githubusercontent.com/cb7ed4d28c8df19eb3b269fe0cad477d17621500/687474703a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d417061636865253230322d627269676874677265656e2e737667\" alt=\"Apache 2\" data-canonical-src=\"http://img.shields.io/badge/license-Apache%202-brightgreen.svg\" /></a> <br /></p><h2>Project</h2><p>Wasabi A/B Testing Service is a real-time, enterprise-grade, 100% API driven project. Users are empowered to own their own data, and run experiments across web, mobile, and desktop. It’s fast, easy to use, it’s chock full of features, and instrumentation is minimal.</p><p>Learn more about how Wasabi can empower your team to move from hunches to actionable, data-driven user insights with our simple, flexible, and scalable experimentation platform.</p><h3>Features</h3><ul><li><strong>Own your own data</strong> - Wasabi runs on your servers, in the cloud or on-premise, where you have complete control over your data.</li>\n<li><strong>Proven</strong> - Wasabi is battle-tested in production at Intuit, Inc., a financial technology company. Wasabi is the experimentation platform for TurboTax, QuickBooks, Mint.com, and other Intuit offerings.</li>\n<li><strong>High Performance</strong> - Consistent server-side response times for user assignments within 30ms.</li>\n<li><strong>100% API-Driven</strong> - The Wasabi REST API is compatible with any language and environment.</li>\n<li><strong>Platform Agnostic</strong> - Uniform, consistent testing across Web, mobile, desktop. Also supports front-end, back-end integrations.</li>\n<li><strong>Real-time user assignments</strong> - Assign users into experiments in real time, to preserve traffic for other parallel A/B tests.</li>\n<li><strong>Cloud and on-premise</strong> - Designed to live in the cloud or in your own data center.</li>\n<li><strong>Analytics</strong> - Core experiment analytics and metrics visualization out of the box, as well as the ability to send data to your existing analytics infrastructure.</li>\n<li><strong>Pluggable</strong> - Well-defined interfaces for plugging in your own access control, sending data to data pipelines, and providing fully custom bucket allocations.</li>\n<li><strong>Experiment Management UI</strong> - Setup and manage experiments via a modern Web interface. Management via REST API is also possible.</li>\n<li><strong>Dockerized</strong> - Spin up a Wasabi Docker instance in 5 minutes and be in production with the platform, instrumentation, and experiments within a day.</li>\n</ul><h3>User Interface</h3><ul><li><strong>Create an experiment and its buckets:</strong>\n<a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://camo.githubusercontent.com/2e4a1b3b58c231a9b2ee753131d28b8982f751c5/68747470733a2f2f696e747569742e6769746875622e696f2f7761736162692f76312f67756964652f696d616765732f726561646d652f4372656174654275636b65742e706e67\"><img src=\"https://camo.githubusercontent.com/2e4a1b3b58c231a9b2ee753131d28b8982f751c5/68747470733a2f2f696e747569742e6769746875622e696f2f7761736162692f76312f67756964652f696d616765732f726561646d652f4372656174654275636b65742e706e67\" alt=\"\" data-canonical-src=\"https://intuit.github.io/wasabi/v1/guide/images/readme/CreateBucket.png\" /></a></li>\n<li><strong>Filter which customers are considered for your experiment:</strong>\n<a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://camo.githubusercontent.com/86693dfd1865dc803f40a0a61786a1f573903968/68747470733a2f2f696e747569742e6769746875622e696f2f7761736162692f76312f67756964652f696d616765732f726561646d652f5365676d656e746174696f6e52756c65732e706e67\"><img src=\"https://camo.githubusercontent.com/86693dfd1865dc803f40a0a61786a1f573903968/68747470733a2f2f696e747569742e6769746875622e696f2f7761736162692f76312f67756964652f696d616765732f726561646d652f5365676d656e746174696f6e52756c65732e706e67\" alt=\"\" data-canonical-src=\"https://intuit.github.io/wasabi/v1/guide/images/readme/SegmentationRules.png\" /></a></li>\n<li><strong>Follow your currently running experiments:</strong>\n<a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://camo.githubusercontent.com/f0372ebe376391b70abe344675870d8830e32621/68747470733a2f2f696e747569742e6769746875622e696f2f7761736162692f76312f67756964652f696d616765732f726561646d652f4578706572696d656e744c6973742e706e67\"><img src=\"https://camo.githubusercontent.com/f0372ebe376391b70abe344675870d8830e32621/68747470733a2f2f696e747569742e6769746875622e696f2f7761736162692f76312f67756964652f696d616765732f726561646d652f4578706572696d656e744c6973742e706e67\" alt=\"\" data-canonical-src=\"https://intuit.github.io/wasabi/v1/guide/images/readme/ExperimentList.png\" /></a></li>\n<li><strong>Track your experiment results in real-time:</strong>\n<a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://camo.githubusercontent.com/26570e8c8a76366b25111ee208473c5f85b057ee/68747470733a2f2f696e747569742e6769746875622e696f2f7761736162692f76312f67756964652f696d616765732f726561646d652f4578706572696d656e7444657461696c732e706e67\"><img src=\"https://camo.githubusercontent.com/26570e8c8a76366b25111ee208473c5f85b057ee/68747470733a2f2f696e747569742e6769746875622e696f2f7761736162692f76312f67756964652f696d616765732f726561646d652f4578706572696d656e7444657461696c732e706e67\" alt=\"\" data-canonical-src=\"https://intuit.github.io/wasabi/v1/guide/images/readme/ExperimentDetails.png\" /></a></li>\n</ul><h2>Get Started</h2><p>The following steps will help you install the needed tools, then build and run a complete Wasabi stack.</p><h4>Bootstrap Your Environment</h4><h5>Mac OS</h5><div class=\"highlight highlight-source-shell\"><pre>% /usr/bin/ruby \\\n  -e \"$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)\"\n% brew install git\n% git clone https://github.com/intuit/wasabi.git\n% cd wasabi\n% ./bin/wasabi.sh bootstrap</pre></div><p>Installed tools include: <a href=\"http://brew.sh\" rel=\"nofollow\">homebrew 0.9</a>, <a href=\"https://git-scm.com\" rel=\"nofollow\">git 2</a>,\n<a href=\"https://maven.apache.org\" rel=\"nofollow\">maven 3</a>, <a href=\"http://www.oracle.com/technetwork/java/javase/overview/index.html\" rel=\"nofollow\">java 1.8</a>,\n<a href=\"https://docker.com\" rel=\"nofollow\">docker 1.12</a>, <a href=\"https://nodejs.org/en\" rel=\"nofollow\">node 6</a> and <a href=\"https://www.python.org\" rel=\"nofollow\">python 2.7</a>.</p><h5>Ubuntu</h5><p>Bootstrapping on Ubuntu requires sudo privileges to install all the required dependencies. You will be prompted to enter your password. Currently only 16.04 (x64) is supported.</p><div class=\"highlight highlight-source-shell\"><pre>% sudo apt-get install git\n% git clone https://github.com/intuit/wasabi.git\n% cd wasabi\n% ./bin/wasabi.sh bootstrap\n% sudo reboot</pre></div><p>NOTE: A reboot is required after running the bootstrap command on Ubuntu.</p><p>For all other processes (build, start etc.) the commands are same for Ubuntu and Mac OS.</p><p>Installed tools include: <a href=\"https://git-scm.com\" rel=\"nofollow\">git 2</a>,\n<a href=\"https://maven.apache.org\" rel=\"nofollow\">maven 3</a>, <a href=\"http://openjdk.java.net/projects/jdk8/\" rel=\"nofollow\">OpenJdk 8</a>,\n<a href=\"https://docker.com\" rel=\"nofollow\">docker 1.12</a>, <a href=\"https://nodejs.org/en\" rel=\"nofollow\">node 6</a> and <a href=\"https://www.python.org\" rel=\"nofollow\">python 2.7</a></p><p>Similar tooling will work for Windows. Contribute a patch :)</p><h4>Start Wasabi</h4><p>Now that we have the necessary tools in place, let's move on to build and start Wasabi, followed by issuing a <em>ping</em>\ncommand to verify the build:</p><div class=\"highlight highlight-source-shell\"><pre>% ./bin/wasabi.sh build start\n...\nwasabi is operational:\n  ui: % open http://localhost:8080     note: sign in as admin/admin\n  ping: % curl -i http://localhost:8080/api/v1/ping\n  debug: attach to localhost:8180\n% curl -i http://localhost:8080/api/v1/ping\nHTTP/1.1 200 OK\nDate: Wed, 25 May 2016 00:25:47 GMT\n...\nX-Application-Id: wasabi-api-20151215171929-SNAPSHOT-development\nContent-Type: application/json\nTransfer-Encoding: chunked\nServer: Jetty(9.3.z-SNAPSHOT)\n{\n  \"componentHealths\":[\n    {\n      \"componentName\":\"Experiments Cassandra\",\n      \"healthy\":true\n    },\n    {\n      \"componentName\":\"MySql\",\"healthy\":true\n    }\n  ],\n  \"wasabiVersion\":\"wasabi-api-20151215171929-SNAPSHOT-development\"\n}</pre></div><p>Congratulations! You are the proud owner of a newly minted Wasabi instance. :)</p><h3>Running Wasabi with remote storage</h3><h5>Set Mysql and Cassandra credentials</h5><ul><li>Modify /pom.xml to set the values that apply to your environment</li>\n</ul><h5>Download Cassandra migration tool <a href=\"https://oss.sonatype.org/content/repositories/public/com/builtamont/cassandra-migration/0.9/cassandra-migration-0.9-jar-with-dependencies.jar\" rel=\"nofollow\">https://oss.sonatype.org/content/repositories/public/com/builtamont/cassandra-migration/0.9/cassandra-migration-0.9-jar-with-dependencies.jar</a></h5><h5>Set up your environment variables</h5><ul><li>Set location of the migration tool</li>\n</ul><div class=\"highlight highlight-source-shell\"><pre>export CASSANDRA_MIGRATION=/location/of/cassandra-migration-0.9-jar-with-dependencies.jar</pre></div><ul><li>Set location of migration scripts within your project</li>\n</ul><div class=\"highlight highlight-source-shell\"><pre>export MIGRATION_SCRIPT=/location/of/modules/repository-datastax/src/main/resources/com/intuit/wasabi/repository/impl/cassandra/migration</pre></div><h5>Set up Cassandra tables</h5><div class=\"highlight highlight-source-shell\"><pre>CQLSH_VERSION=&lt;version&gt; CQLSH_USERNAME=&lt;username&gt; CQLSH_PASSWORD=&lt;pwd&gt; CQLSH_HOST=&lt;host&gt; bin/docker/migration.sh</pre></div><h5>Run Wasabi with env variables for remote storage hosts</h5><div class=\"highlight highlight-source-shell\"><pre>MYSQL_HOST=&lt;mysql_host&gt; NODE_HOST=&lt;cassandra_host&gt; ./bin/wasabi.sh start:wasabi</pre></div><h5>Run Wasabi outside of docker with WASABI_CONFIGURATION for remote storage hosts</h5><div class=\"highlight highlight-source-shell\"><pre>WASABI_CONFIGURATION=\"\n  -Ddatabase.url.host=$MYSQL_HOST\\\n  -Ddatabase.url.port=$MYSQL_PORT\\\n  -Ddatabase.url.dbname=$MYSQL_DATABASE\\\n  -Ddatabase.user=$MYSQL_USER\\\n  -Ddatabase.password=$MYSQL_PASSWORD\\\n  -Ddatabase.pool.connections.min=$MYSQL_MIN_CONNECTIONS\\\n  -Ddatabase.pool.connections.max=$MYSQL_MAX_CONNECTIONS\\\n  -Dusername=$CASSANDRA_USER\\\n  -Dpassword=$CASSANDRA_PASSWORD\\\n  -DnodeHosts=$CASSANDRA_HOST\\\n  -DtokenAwareLoadBalancingLocalDC=$CASSANDRA_DATACENTER\\\n  -Dapplication.http.port=$PORT\" bash usr/local/wasabi-main-*/bin/run</pre></div><h4>Troubleshooting</h4><ul><li>\n<p>While starting Wasabi, if you see an error when the docker containers are starting up, you could do the following:</p>\n<ul><li>Look at the current docker containers that have been successfully started.</li>\n</ul></li>\n</ul><div class=\"highlight highlight-source-shell\"><pre>% ./bin/wasabi.sh status\nCONTAINER ID        IMAGE                    COMMAND                  CREATED             STATUS              PORTS                                                                     NAMES\n8c12458057ef        wasabi-main              \"entrypoint.sh wasabi\"   25 minutes ago      Up 25 minutes       0.0.0.0:8080-&gt;8080/tcp, 0.0.0.0:8090-&gt;8090/tcp, 0.0.0.0:8180-&gt;8180/tcp    wasabi-main\n979ecc885239        mysql:5.6                \"docker-entrypoint.sh\"   26 minutes ago      Up 26 minutes       0.0.0.0:3306-&gt;3306/tcp                                                    wasabi-mysql\n2d33a96abdcb        cassandra:2.1            \"/docker-entrypoint.s\"   27 minutes ago      Up 27 minutes       7000-7001/tcp, 0.0.0.0:9042-&gt;9042/tcp, 7199/tcp, 0.0.0.0:9160-&gt;9160/tcp   wasabi-cassandra</pre></div><ul><li>The above shell output shows a successful start of 3 docker containers needed by Wasabi: wasabi-main (the Wasabi server),\nwasabi-mysql, and wasabi-cassandra. If any of these are not running, try starting them individually. For example, if the\nMySQL container is running, but Cassandra and Wasabi containers failed to start (perhaps due to a network timeout docker\ncould not download the Cassandra image), do the following:</li>\n</ul><div class=\"highlight highlight-source-shell\"><pre>% ./bin/wasabi.sh start:cassandra\n% ./bin/wasabi.sh start:wasabi</pre></div><h4>Call Wasabi</h4><p>These are the 3 common REST endpoints that you will use to instrument your client application with Wasabi.</p><p>Let's assume that you've created and started an experiment, 'BuyButton,' in the 'Demo_App' application with the following buckets:</p><ul><li>'BucketA': green button (control bucket)</li>\n<li>'BucketB': orange button bucket</li>\n</ul><p>You can assign a user with a unique ID (e.g. 'userID1') to the experiment by making this HTTP request:</p><blockquote>\n<p>Assign a user to experiment and bucket:</p>\n</blockquote><div class=\"highlight highlight-source-shell\"><pre>% curl -H \"Content-Type: application/json\" \\\n    http://localhost:8080/api/v1/assignments/applications/Demo_App/experiments/BuyButton/users/userID1\n{  \n   \"cache\":true,\n   \"payload\":\"green\",\n   \"assignment\":\"BucketA\",\n   \"context\":\"PROD\",\n   \"status\":\"NEW_ASSIGNMENT\"\n}</pre></div><p>Now the 'userID1' user is assigned into the 'BucketA' bucket. Let's further record an impression, meaning the user has seen a given experience:</p><blockquote>\n<p>Record an impression:</p>\n</blockquote><div class=\"highlight highlight-source-shell\"><pre>% curl -H \"Content-Type: application/json\" \\\n    -d \"{\\\"events\\\":[{\\\"name\\\":\\\"IMPRESSION\\\"}]}\" \\\n    http://localhost:8080/api/v1/events/applications/Demo_App/experiments/BuyButton/users/userID1</pre></div><p>If the 'userID1' user performs an action such as clicking the Buy button, you'd record that action with the following request:</p><blockquote>\n<p>Record an action:</p>\n</blockquote><div class=\"highlight highlight-source-shell\"><pre>% curl -H \"Content-Type: application/json\" \\\n    -d \"{\\\"events\\\":[{\\\"name\\\":\\\"BuyClicked\\\"}]}\" \\\n    http://localhost:8080/api/v1/events/applications/Demo_App/experiments/BuyButton/users/userID1</pre></div><h4>Explore Various Resources</h4><p>The following developer resources are available:</p><blockquote>\n<p>API: Swagger API playground</p>\n</blockquote><div class=\"highlight highlight-source-shell\"><pre>% ./bin/wasabi.sh resource:api</pre></div><blockquote>\n<p>Javadoc</p>\n</blockquote><div class=\"highlight highlight-source-shell\"><pre>% ./bin/wasabi.sh resource:doc</pre></div><blockquote>\n<p>Wasabi UI</p>\n</blockquote><div class=\"highlight highlight-source-shell\"><pre>% ./bin/wasabi.sh resource:ui</pre></div><blockquote>\n<p>Cassandra: cqlsh shell</p>\n</blockquote><div class=\"highlight highlight-source-shell\"><pre>% ./bin/wasabi.sh resource:cassandra</pre></div><blockquote>\n<p>MySQL: mysql shell</p>\n</blockquote><div class=\"highlight highlight-source-shell\"><pre>% ./bin/wasabi.sh resource:mysql</pre></div><blockquote>\n<p>Java Debugger: Remote attach configuration</p>\n</blockquote><div class=\"highlight highlight-source-shell\"><pre>-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8180</pre></div><h4>Stop Wasabi</h4><p>Alas, all good things must come to an end. Let's clean things up a bit stop the newly created Wasabi stack:</p><p>At this point in time, we now have all the requisite tools installed, and subsequent invocations of Wasabi will\nstart up much more quickly.</p><div class=\"highlight highlight-source-shell\"><pre>% ./bin/wasabi.sh stop</pre></div><h4>Get Familiar with wasabi.sh</h4><p>Further, there are a number of additional wasabi.sh options available you should become familiar with:</p><div class=\"highlight highlight-source-shell\"><pre>% ./bin/wasabi.sh --help\n  usage: wasabi.sh [options] [commands]\n  options:\n    -e | --endpoint [ host:port ]          : api endpoint; default: localhost:8080\n    -v | --verify [ true | false ]         : verify installation configuration; default: false\n    -s | --sleep [ sleep-time ]            : sleep/wait time in seconds; default: 30\n    -h | --help                            : help message\n  commands:\n    bootstrap                              : install dependencies\n    build                                  : build project\n    start[:cassandra,mysql,wasabi]         : start all, cassandra, mysql, wasabi\n    test                                   : test wasabi\n    stop[:wasabi,cassandra,mysql]          : stop all, wasabi, cassandra, mysql\n    resource[:ui,api,doc,cassandra,mysql]  : open resource api, javadoc, cassandra, mysql\n    status                                 : display resource status\n    remove[:wasabi,cassandra,mysql]        : remove all, wasabi, cassandra, mysql\n    package                                : build deployable packages\n    release[:start,finish]                 : promote release</pre></div><h2>Develop</h2><h4>Build and Run Wasabi Server</h4><div class=\"highlight highlight-source-shell\"><pre>% mvn package\n% ./bin/wasabi.sh start:cassandra,mysql\n% (cd modules/main/target; \\\n    WASABI_CONFIGURATION=\"-DnodeHosts=localhost -Ddatabase.url.host=localhost\" ./wasabi-main-*-SNAPSHOT-development/bin/run) &amp;\n% curl -i http://localhost:8080/api/v1/ping\n...</pre></div><p>The runtime logs can be accessed executing the following command in a another shell:</p><blockquote>\n<p>Viewing runtime logs:</p>\n</blockquote><div class=\"highlight highlight-source-shell\"><pre>% tail -f modules/main/target/wasabi-main-*-SNAPSHOT-development/logs/wasabi-main-*-SNAPSHOT-development.log</pre></div><h4>Build and Run Wasabi UI</h4><div class=\"highlight highlight-source-shell\"><pre>% cd modules/ui\n% grunt build</pre></div><div class=\"highlight highlight-source-shell\"><pre>% grunt serve</pre></div><h4>Stop Wasabi</h4><div class=\"highlight highlight-source-shell\"><pre>% ./bin/wasabi.sh stop</pre></div><p>Now while that was fun, in all likelihood you will be using an IDE to work on Wasabi. In doing so, you need only\nadd the configuration information above to the JVM commandline prior to startup:</p><blockquote>\n<p>Wasabi runtime configuration:</p>\n</blockquote><div class=\"highlight highlight-source-shell\"><pre>-DnodeHosts=localhost -Ddatabase.url.host=localhost</pre></div><h4>Run Integration Tests</h4><p>Code changes can readily be verified by running the growing collection of included integration tests:</p><div class=\"highlight highlight-source-shell\"><pre>% ./bin/wasabi.sh start test stop</pre></div><h5>Troubleshooting</h5><p>Integration tests might fail intermittently due to a time drift issue in docker containers on Mac OSX.</p><p>When the Mac sleeps and wakes back up, there is a lag created between the clock in the Mac vs the\nrunning docker containers. This is a known issue in Docker for Mac.</p><p>This can be fixed by running the following command:</p><div class=\"highlight highlight-source-shell\"><pre>% docker run --rm --privileged alpine hwclock -s</pre></div><p>The above command will need to be run every time when there is a time drift.</p><p>To automatically run this command and update the time each time the Mac wakes up, you could install\nthe following agent:</p><div class=\"highlight highlight-source-shell\"><pre>% curl https://raw.githubusercontent.com/arunvelsriram/docker-time-sync-agent/master/install.sh | bash</pre></div><p>You can read more about this at: <a href=\"https://blog.shameerc.com/2017/03/quick-tip-fixing-time-drift-issue-on-docker-for-mac\" rel=\"nofollow\">quick-tip-fixing-time-drift-issue-on-docker-for-mac</a></p><h2>Package and Deploy at Scale</h2><p>Wasabi can readily be packaged as installable <em>rpm</em> or <em>deb</em> distributions and deployed at scale as follows:</p><blockquote>\n<p>Package by running integration tests 1st:</p>\n</blockquote><div class=\"highlight highlight-source-shell\"><pre>% ./bin/wasabi.sh start package</pre></div><blockquote>\n<p>Package without integration tests, if needed:</p>\n</blockquote><div class=\"highlight highlight-source-shell\"><pre>% ./bin/wasabi.sh -t false package</pre></div><blockquote>\n<p>Find generated package files:</p>\n</blockquote><div class=\"highlight highlight-source-shell\"><pre>% find . -type f \\( -name \"*.rpm\" -or -name \"*.deb\" \\)</pre></div><p>Note: <a href=\"http://www.oracle.com/technetwork/java/javase/overview/index.html\" rel=\"nofollow\">Java 8</a> is a runtime dependency</p><h2>Integrate</h2><p>Wasabi is readily embeddable via the following <em>maven</em> dependency GAV family:</p><div class=\"highlight highlight-text-xml\"><pre>&lt;dependency&gt;\n    &lt;groupId&gt;com.intuit.wasabi&lt;/groupId&gt;\n    &lt;artifactId&gt;wasabi&lt;/artifactId&gt;\n    &lt;version&gt;1.0.20160627213750&lt;build_timestamp&gt;&lt;/version&gt;\n&lt;/dependency&gt;</pre></div><h2>Contribute</h2><p>We greatly encourage contributions! You can add new features, report and fix existing bugs, write docs and\ntutorials, or any of the above. Feel free to open issues and/or send pull requests.</p><p>The <code>master</code> branch of this repository contains the latest stable release of Wasabi, while snapshots are published to the <code>develop</code> branch. In general, pull requests should be submitted against <code>develop</code> by forking this repo into your account, developing and testing your changes, and creating pull requests to request merges. See the <a href=\"https://guides.github.com/activities/contributing-to-open-source/\">Contributing to a Project</a>\narticle for more details about how to contribute in general and find more specific information on how to write code for Wasabi in our <a href=\"https://intuit.github.io/wasabi/v1/guide/index.html#developing-wasabi\" rel=\"nofollow\">user guide</a>.</p><p>Extension projects such as browser plugins, client integration libraries, and apps can be contributed under the <code>contrib</code> directory.</p><p>Steps to contribute:</p><ol><li>Fork this repository into your account on Github</li>\n<li>Clone <em>your forked repository</em> (not our original one) to your hard drive with <code>git clone https://github.com/YOURUSERNAME/wasabi.git</code></li>\n<li>Design and develop your changes</li>\n<li>Add/update unit tests</li>\n<li>Add/update integration tests</li>\n<li>Add/update documentation on <code>gh-pages</code> branch</li>\n<li>Create a pull request for review to request merge</li>\n<li>Obtain 2 approval <em>squirrels</em> before your changes can be merged</li>\n</ol><p>Thank you for your contribution!</p>","id":"965b9cd4-097c-560f-94b6-00ce67a88391","title":"intuit/wasabi","origin_url":"https://github.com/intuit/wasabi","url":"https://github.com/intuit/wasabi","wallabag_created_at":"2018-09-24T16:18:17+00:00","published_at":null,"published_by":"['']","reading_time":10,"domain_name":"github.com","preview_picture":"https://opengraph.githubassets.com/6b71518933139be280b839b74b254bf883d8ad401517eabea88c5f1d20fc4cc9/intuit/wasabi","tags":["open.source","cassandra","testing"],"description":"Support:  Documentation: User Guide, JavaDocs\nA/B Testing Overview:    Continuous Integration: \n\n License:  ProjectWasabi A/B Testing Service is a real-time, enterprise-grade, 100% API driven project...."},{"content":"<p>In the previous two posts of this series (<a href=\"https://www.instaclustr.com/deep-diving-into-cassandra-stress-part-1/\">Part 1</a> and <a href=\"https://www.instaclustr.com/deep-diving-into-cassandra-stress-part-2/\">Part 2</a>) I covered some of the basic commands of <a href=\"https://www.instaclustr.com/apache-cassandra/\">cassandra</a>-stress. In this post I will start looking at the use of the stress YAML file for more advanced stress scenarios, particularly where you want to run stress against a schema that matches one you are planning to use for your application.</p><p>It’s worth noting in the intro that cassandra-stress with a YAML file use a significantly (80%?) different set of code to the standard read/write/mixed commands. So, some assumptions and learnings from the standard commands won’t hold for YAML-driven stress. To cite one example, when running based on YAML, cassandra-stress does not validate that data returned from a select has the expected values as it does with read or mixed.</p><h5>For this article, I’ll reference the following YAML specification file:</h5><p>Before explaining the contents here, let’s see what happens when we run it with the following simple scenario:<br /><code>cassandra-stress user profile=file:///eg-files/stressprofilemixed.yaml no-warmup ops(insert=1) n=100 -rate threads=1 -node x.x.x.x</code></p><p>After running this on an empty cluster, I ran <code>select count(*) from eventsrawtest;</code>. The result? 345 rows – probably not you would have guessed. Here’s how cassandra-stress gets to that:</p><ul><li>n=100 counts number of insert batches, not number of individual insert operations</li>\n<li>Each batch will contain 1 partition’s data (due to partitions=fixed(1) setting) and all 15 of the rows in the partition. There are 15 rows in every partition as the single cluster key (time) has a cluster setting of fixed(15). All the rows in the partition will be included in the batch due to the select: fixed(10)/10 setting (ie changing this to say fixed(5)/10 would result in half the rows from the partition being include in any given batch).</li>\n<li>100 batches of 15 rows each gets you to 1500 rows so how did we end up with 345? This is due (primarily, in this case) to the relatively small range of potential values for the bucket_time. This results in a high overlap in the partition key values that end up getting generated by the uniform distributions. To demonstrate, changing the population of bucket_time to uniform(1..1288) results in 540 rows. In most cases, you want to initially insert data with no overlap to build up a base data set for testing. To facilitate this, I’ve recently submitted a cassandra-stress enhancement that provides sequential generation of seed values the same as used with the write command (<a href=\"https://issues.apache.org/jira/browse/CASSANDRA-12490\">https://issues.apache.org/jira/browse/CASSANDRA-12490</a>). Changing the uniform() distribution to seq() results in the expected 1500 rows being inserted by this command.</li>\n</ul><h5>Let’s look at some of the other column settings:</h5><ul><li><strong>population</strong> – determines the distribution of seed values used in the random data generation. By controlling the distribution of the seed values you control the distribution of the actual inserted values. So, for example uniform(1..100) will allow for up 100 different values each with the same chance of being selected. guassian(1..100) will also allow for up to 100 different values but as they will follow a guassian (otherwise known as normal or bell-curve) distribution, the values around the middle will have a much higher chance of being selected than the values at the extremes (so there will be a set of values more likely to get repeated and some which will occur very infrequently).</li>\n<li><strong>size</strong> – determines the size (length in bytes) of the of the values created for the field.</li>\n<li><strong>cluster</strong> – only applies to clustering columns, specifies the number of values for the column appearing in a single partition. The maximum number of rows in a partition is therefore the product of the maximum number of row of each clustering column (eg max(row1) * max(row 2) * max(row3)).</li>\n</ul><h5>We covered most of the insert settings in the introductory points but here’s a recap:</h5><ul><li><strong>partitions</strong>: the number of different partitions to include in each generated insert batch. Once a partition is chosen for inclusion in a batch, all rows in the partition will become eligible for inclusion and then be filtered according to the select setting. Using, uniform(1..5) would result in each batches containing between 1 and 5 partitions worth of data (with an equal chance of each number in the range).</li>\n<li><strong>batchtype</strong>: logged or unlogged – determines the cassandra batch type to use</li>\n<li><strong>select</strong>: select determines the portion of rows from a partition to select (at random) for inclusion in particular batch. So, for example, fixed(5)/10 would include 50% of rows from the selected partition in each batch. uniform(1..10)/10 would result in between 10% and 100% of rows in the partition being included in the batch with a different select percentage being randomly picked for each partition in each batch.</li>\n</ul><h5>The final section the yaml file that bears some explanation is the queries section. For each query, you specify:</h5><ul><li>A name for the query (pull-for-rollup, get-a-value) which are used to refers to the queries when specifying the mix of operations through the cassandra-stress command line.</li>\n<li><strong>cql</strong> – The actual query with ? characters where values from the population will be substituted in.</li>\n<li><strong>fields</strong> – either samerow or multirow. For samerow, the key values to use for the select will be picked at random (following the same general population rules as for insert) for the list of row keys that has been generated for inserting. For multirow, each of the column values making up the key will be independently randomly selected so there is a chance of generating keys for the selection parameters that don’t exist in the set of data that will/could be inserted according the the population settings.</li>\n</ul><h5>The ops command specified as part of the command line controls the mix of different operations to run. Take for example the following command:</h5><p><code>cassandra-stress user profile=file:///eg-files/stressprofilemixed.yaml ops(insert=1, pull_for_rollup=1, get-value=10) n=120 -node x.x.x.x</code></p><p>This will execute insert batches, pull_for_rollup queries and get-value queries in the ratio 1:1:10. So for this specific example, we’d get 10 inserts, 10 pull_for_rollup queries and 100 get-value queries.</p><p>Hopefully that’s explained the key information you need to use a YAML profile for running cassandra stress. In future instalments I’ll take a look at some of the remaining command line options and walk through a full end-to-end example of designing and executing a test.</p><p>Click here for <a href=\"https://www.instaclustr.com/blog/2016/08/19/deep-diving-into-cassandra-stress-part-1/\">Part One: </a><a href=\"https://www.instaclustr.com/deep-diving-into-cassandra-stress-part-1/\">Deep Diving into Cassandra Stress</a><br />Click here for <a href=\"https://www.instaclustr.com/deep-diving-into-cassandra-stress-part-2/\">Part Two: Mixed Command</a></p>","id":"d7cce620-feeb-572c-bc3f-3a4fd803fdf6","title":"Deep Diving cassandra-stress - Part 3 (Using YAML Profiles) - Instaclustr","origin_url":"https://www.instaclustr.com/deep-diving-cassandra-stress-part-3-using-yaml-profiles/","url":"https://www.instaclustr.com/deep-diving-cassandra-stress-part-3-using-yaml-profiles/","wallabag_created_at":"2018-09-13T14:57:14+00:00","published_at":"2016-08-24T05:03:19+00:00","published_by":"['']","reading_time":5,"domain_name":"www.instaclustr.com","preview_picture":"https://www.instaclustr.com/wp-content/uploads/2021/10/cs-article3.png","tags":["stress","cassandra","cassandra.stress","testing"],"description":"In the previous two posts of this series (Part 1 and Part 2) I covered some of the basic commands of cassandra-stress. In this post I will start looking at the use of the stress YAML file for more adv..."},{"content":"<p>This is the second of a series of articles explain the operations of cassandra-stress. See here for <a href=\"https://www.instaclustr.com/deep-diving-into-cassandra-stress-part-1/\" target=\"_blank\" rel=\"noopener\">Part 1</a>.</p><p>This series of blogs has been created as part of my prep for my Cassandra summit talk ‘Load Testing Cassandra Applications’.</p><p>In this post we’ll examine the operation of the mixed command in <a href=\"https://www.instaclustr.com/apache-cassandra/\">Cassandra</a> stress and along with that some option for changing the schema used by stress (without using the yaml configuration for a complete custom run).</p><p>Firstly, let’s look at the most simple invocation of the mixed command:</p><p><code>cassandra-stress mixed n=100 -node x.x.x.x</code></p><p>First thing to note about this command is that for it to work you need to have run a write command to create the schema and populate data before the run. The write command should be run with at least the same number of operations as the mixed command to ensure that read commands will all retrieve data. For example, to prepare for the above command you should run:</p><p><code>cassandra-stress write n=100 -node x.x.x.x</code></p><p>If you haven’t written the right data before you run the mixed test then you will receive errors like the following:</p><p><code>java.io.IOException: Operation x0 on key(s) [38374d394b504d353430]: Data returned was not validated</code></p><p>This is because cassandra-stress validates the data returned from the select operations against the generated data set expected for the row (and in this case no data was returned).</p><p>So, once you’re set up correctly, what will the command actually do? The key default settings that come into play are:</p><ul><li>Consistency level: LOCAL_ONE – particularly significant for reads as it means only a single node will need to perform each read (vs multiple nodes for the more common QUORUM consistency levels)</li> <li>Command Ratios: {READ=1.0, WRITE=1.0} – the operations will be split evenly between reads and writes</li> <li>Command Clustering Distribution: clustering=GAUSSIAN(1..10) – determines the number of consecutive read or write operations to conduct consecutively. So, in this case will perform between 1 to 10 reads before performing between 1 to 10 writes and then switching back to reads. Due to this clustering, the actual ratio of reads to writes may differ from the target specified in command ratios for small runs such as this. However, it should even out over the course of a longer run.</li> <li>Population Distribution: Gaussian: min=1,max=100,mean=50.500000,stdev=16.500000 – unlike the write command, which uses a sequence from 1 to number of ops, mixed uses randomly generated numbers from 1 to the number of ops as part of the seed for the actual values. As the range is the same as write operations, the values are guaranteed to overlap between write and mixed but the the mixed run will potentially not visit all possible values and will visit them in a random order (of seed values).</li> <li>Rate: Auto, min threads = 4, max threads = 1000 – cassandra-stress will perform multiple runs, start at 4 threads and increasing threads with each run until the total operation rate fails to increase for three consecutive runs. The number of threads used will double with each run up to 16 threads and then increase by 1.5 times with each run after that.</li> </ul><p>The rate setting illustrates an interesting point in using cassandra-stress: generally, increasing the number of client threads will increase the load (throughput) you are placing on the cluster. This is because all operations are executed synchronously (in order to time them) and so more threads allow more operations to be simultaneously thrown at the cluster. Of course, like any multi-threaded system, there is an overhead incurred managing threads on the stress client and a limit to how much work the client can do before it becomes a bottleneck to the test. So, increase threads to increase the load on your cluster but check when you hit the limit that it’s actually your cluster reaching its limit not your stress client.</p><p>That’s it for the mixed command and associated info. Future installments will look at some of the other key options and the yaml configuration file.</p><p>Click here for <a href=\"https://www.instaclustr.com/deep-diving-into-cassandra-stress-part-1/\">Part One: D</a><a href=\"https://www.instaclustr.com/deep-diving-into-cassandra-stress-part-1/\" target=\"_blank\" rel=\"noopener\">eep Diving into Cassandra Stress</a><br />Click here for <a href=\"https://www.instaclustr.com/deep-diving-cassandra-stress-part-3-using-yaml-profiles/\" target=\"_blank\" rel=\"noopener\">Part Three: Using YAML Profiles</a></p>","id":"8514554d-37af-5231-90d2-40e59dc0280b","title":"Deep Diving into cassandra-stress - Part 2 (Mixed Command) - Instaclustr","origin_url":"https://www.instaclustr.com/deep-diving-into-cassandra-stress-part-2/","url":"https://www.instaclustr.com/deep-diving-into-cassandra-stress-part-2/","wallabag_created_at":"2018-09-13T14:57:04+00:00","published_at":"2016-08-23T04:16:17+00:00","published_by":"['']","reading_time":3,"domain_name":"www.instaclustr.com","preview_picture":"https://www.instaclustr.com/wp-content/uploads/Insta_Website_Social-Share-Thumbnail_rebrand.png","tags":["stress","cassandra","cassandra.stress","testing"],"description":"This is the second of a series of articles explain the operations of cassandra-stress. See here for Part 1.This series of blogs has been created as part of my prep for my Cassandra summit talk ‘Load T..."},{"content":"<h2>Overview</h2><p>This is the first in a series of blog post I’m planning to create as part of my prep for my Cassandra summit talk ‘Load Testing Cassandra Applications’.</p><p>cassandra-stress is a great utility for stress testing <a href=\"https://www.instaclustr.com/apache-cassandra/\">Cassandra</a>. However, available documentation is a little sparse and it not always entirely clear what load cassandra-stress will generate in a given situation. In this series of blog posts, I plan to walk through a number of cassandra stress scenarios examining exactly how cassandra-stress behaves.</p><p>For this series, I will be using the latest 3.x version of cassandra-stress. If I notice any differences related to a particular point version of Cassandra I will call them out.</p><p>In this first post, I will look at what is about the most basic cassandra-stress command you can run:<br /><code>cassandra-stress write n=10 -node x.x.x.x</code></p><p>I chose this command for two reasons: firstly, using a simple command will allow us to look at some of the basic functions that apply across any cassandra-stress command and secondly, in almost all scenarios, you will want to execute a write to populate a cluster with data before running a read or mixed scenario.</p><h2>cassandra-stress</h2><p>Let’s start by looking at that components of the command itself:</p><ul><li><code>cassandra-stress</code>: invokes a shell script which in turn invokes the main function of the Java class org.apache.cassandra.stress.Stress</li> <li><code>write</code>: execute write operations (other options being read, mixed, user, counter_write and counter_read)</li> <li><code>n=10</code>: execute 10 operations</li> <li><code>-node x.x.x.x</code>: the address of a node in the cluster to establish the initial connection</li> </ul><p>Filling in with defaults, here’s all the settings cassandra-stress will actually use for the run (from my in-progress implementation of <a href=\"https://issues.apache.org/jira/browse/CASSANDRA-11914\" target=\"_blank\" rel=\"noopener noreferrer\">CASSANDRA-11914</a>):</p><h2>Step by Step</h2><p>As you can see, there is a lot going on behind the scenes. So. let’s walk-through step by step what cassandra-stress actually does when you execute this command:</p><ol><li> <ol><li>The options provided through the command line are parsed and filled in with a whole range of default options as necessary (will touch on important defaults below and more in future articles). Interestingly, at this stage a valid cassandra.yaml will need to be loaded. However, as far as I could tell this is just a side effect of cassandra-stress using some core Cassandra classes and the contents of the cassandra.yaml have no effect on the actual cassandra-stress operations.</li>\n<li>The Cassandra Java driver is used to connect to the node specified in the command line. From this node, the driver retrieves the node list and token map for the cluster and then initiates a connection to each node in the cluster.</li>\n<li>A create keyspace (if one doesn’t already exist) command is executed with the following definition:<br />While this definition is a reasonable choice for a simple default, it’s important to note that this is unlikely to be representative of a keyspace you would want to run in production. By far the most common production scenario would be to use NetworkTopologyStrategy and a replication factor of 3. To have cassandra-stress create a keyspace with this strategy you would need to drop any existing keyspace and add the following parameters to the cassandra-stress command line:<br /><code>-schema replication(strategy=NetworkTopologyStrategy,DC_NAME=3)</code><br />Replace DC_NAME with the actual name of your Cassandra data center. On some systems you may also need to escape the brackets ie. <code>replication\\(...\\)</code></li>\n<li>Once the keyspace is created, cassandra-stress creates two tables in the keyspace: standard1 and counter1. We’ll ignore counter1 for now as it’s not used in this test. The definition of the standard1 table created is as follows:<br />While, again, this is a reasonable choice for a simple default, there are a few characteristics to keep in mind if you are trying to draw conclusions from performance using this table definition:\n<ul><li>There is no clustering key, so 1 row per partition – potentially very different performance to a scenario with many rows per partition.</li>\n<li>Compression is disabled – the overhead of compression is typically not huge but could be significant.</li>\n<li>Compact Storage is enabled – this is not enabled by default and will result in smaller representation of the data on disk (although minimal difference with Cassandra 3.x).</li>\n</ul><p>I’ll cover options for using different schemas in a later installment of this series.</p></li>\n<li>cassandra-stress will attempt to make a jmx connection to the nodes in the cluster to collect garbage collection stats. If the attempt fails, the run will proceed without collection garbage collection stats.</li>\n<li>Next, cassandra-stress will run a warmup. This is a standard practice in load testing to reduce variation from start-up variation such as code being loaded to memory and JVM hotspot compilers. The number of warm-up iterations is the lesser 25% of the target of operations or 50k – 2 operations in this trivial example. The warm-up operations are basically the same as the test operations except not timed so I won’t go into them in detail.</li>\n<li>We’ve entered the actual load test phase. cassandra-stress creates 200 client threads and begins executing the target number of operations. In a real test, using the <strong>-rate</strong> option to control the number of client threads is a good way to control load on the cluster.<br />The first attempted operation will create a CQL prepared statement as follows:<br /><code>UPDATE \"standard1\" SET \"C0\" = ?,\"C1\" = ?,\"C2\" = ?,\"C3\" = ?,\"C4\" = ? WHERE KEY=?</code><br />Although we were probably expecting an INSERT statement, updates and inserts are identical in terms of Cassandra implementation so we can expect performance to be the same.This prepared statement will then be will be executed 10 times with different, random data generated for each execution. The statement will be executed with consistent level LOCAL_ONE.cassandra-stress seeds the random generation with a static string plus the column name and a seed number which for the write command defaults to sequentially used numbers from 1 to the number of operations. That means that each column will get different values but the set of values generated will be the same over multiples runs. Generating a static set of values is necessary for read tests but does have the side effect that if you were to run our sample operation (write n=10) 1000 times the end result would still be just 10 rows of data in the table.</li>\n<li>Finally, cassandra-stress prints its results. Here’s an example from a run of this command:\n<p>Many of these results are self explanatory but some bear further explanation:<br /><strong>Op rate</strong> is the rate of execution commands. <strong>Partition rate</strong> is that rate that partitions were visited (updated or read) by those commands and <strong>Row rate</strong> is that rate that rows were visited. For simple, single-row commands all three rates will be equal. The rates will vary in more complex scenarios where a single operation might visit multiple partitions and rows.<br />Similarly, <strong>Total partitions</strong> is the total number of partitions visited during the test. It’s worth noting that this is not unique partitions so even in some write-only scenarios it may not reflect the total number of partitions created by the test.<br />The <strong>GC</strong> statistics report on garbage collection and are zero in this case as JMX ports were blocked to the test cluster.</p></li>\n</ol></li>\n</ol><h2>Conclusion</h2><p>Well, that’s a lot to write about a simple test that inserts 10 rows into a table. Putting it together has helped improved my understanding of cassandra-stress, I hope it’s useful for you too. In future installments, I’ll look some more into the different data generation operations, mixed test and customers schemas using the YAML configuration file. Let me know in the comments if there are any particular areas of interest for the future articles.</p><p>Click here for <a href=\"https://www.instaclustr.com/blog/2016/08/23/deep-diving-into-cassandra-stress-part-2/\" target=\"_blank\" rel=\"noopener\">Part Two: Mixed Command</a><br />Click here for <a href=\"https://www.instaclustr.com/deep-diving-cassandra-stress-part-3-using-yaml-profiles/\" target=\"_blank\" rel=\"noopener\">Part Three: Using YAML Profiles</a></p>","id":"25e43042-097b-5768-9b7d-2c8713b3e074","title":"Deep Diving into cassandra-stress (Part 1) - Instaclustr","origin_url":"https://www.instaclustr.com/deep-diving-into-cassandra-stress-part-1/","url":"https://www.instaclustr.com/deep-diving-into-cassandra-stress-part-1/","wallabag_created_at":"2018-09-13T14:56:56+00:00","published_at":"2016-08-19T01:20:07+00:00","published_by":"['']","reading_time":6,"domain_name":"www.instaclustr.com","preview_picture":"https://www.instaclustr.com/wp-content/uploads/Insta_Website_Social-Share-Thumbnail_rebrand.png","tags":["stress","cassandra","cassandra.stress","testing"],"description":"OverviewThis is the first in a series of blog post I’m planning to create as part of my prep for my Cassandra summit talk ‘Load Testing Cassandra Applications’.cassandra-stress is a great utility for ..."}],"tagSets":[{"tag":"cassandra","articles":[{"content":"<p>This is the second post in my series on improving node density and lowering costs with Apache Cassandra. In the <a href=\"https://rustyrazorblade.com/post/2025/03-streaming/\">previous post</a>, I examined how streaming performance impacts node density and operational costs. In this post, I’ll focus on compaction throughput, and a recent optimization in Cassandra 5.0.4 that significantly improves it, <a href=\"https://issues.apache.org/jira/browse/CASSANDRA-15452\" target=\"_blank\">CASSANDRA-15452</a>.</p><p>This post assumes some familiarity with Apache Cassandra storage engine fundamentals. The documentation has a nice <a href=\"https://cassandra.apache.org/doc/stable/cassandra/architecture/storage_engine.html\" target=\"_blank\">section covering the storage engine</a> if you’d like to brush up before reading this post.</p><h2 id=\"the-compaction-bottleneck\">The Compaction Bottleneck</h2><p>Compaction in Cassandra is the process of merging multiple SSTables and writing out new ones, discarding tombstones, resolving overwrites, and generally organizing data for efficient reads. It’s an I/O intensive background operation that directly competes with foreground operations for system resources. In a later post I’ll look at how compaction strategies impact node density, but for now, I’ll just focus on throughput.</p><h2 id=\"why-compaction-throughput-matters-for-node-density\">Why Compaction Throughput Matters for Node Density</h2><p>As we continue to increase the amount of data we store per node, compaction performance becomes increasingly important. It affects:</p><ul><li>How quickly the system can reclaim disk space</li>\n<li>Whether the cluster can keep up with incoming writes</li>\n<li>Read latency, minimizing SSTables per read</li>\n<li>How fast nodes are able to join a new cluster</li>\n</ul><p>Simply put: as your data volume and write throughput increase, compaction throughput must as well. If it doesn’t, you’ll hit a performance wall that effectively caps your maximum practical node density.</p><p>Despite the significant improvements to compaction throughput over the years, there are some circumstances where compaction performance is inadequate. Let’s take a look at the reason why, then dive into what can be done about it.</p><p>When doing any performance evaluation, it’s important to understand how to measure where your time is spent. A lot of folks make incorrect assumptions, and then waste a lot of time trying to optimize something that doesn’t matter. I’ve written several posts about how useful profiling with the <a href=\"https://rustyrazorblade.com/post/2023/2023-11-07-async-profiler\">async-profiler</a> can be from an application perspective. For looking at the OS and hardware, the eBPF based toolkit <a href=\"https://rustyrazorblade.com/post/2023-11-14-bcc-tools\">bcc-tools</a> can help you identify process bottlenecks. I’ve used these tools extensively over the years, and in this post I’ll show how they’ve helped identify two major performance bottlenecks in compaction. My <a href=\"https://github.com/rustyrazorblade/easy-cass-lab\" target=\"_blank\">easy-cass-lab</a> software includes all these tools, as well as integration with <a href=\"https://axonops.com/\" target=\"_blank\">AxonOps</a> for Cassandra dashboards and operational tooling.</p><h2 id=\"being-10x-smarter-with-our-disk-access\">Being 10x Smarter With Our Disk Access</h2><p>When investigating compaction behavior, I discovered an major inefficiency in how Cassandra was accessing disk. The problem was especially severe in cloud environments with disaggregated storage like AWS EBS, where IOPS (Input/Output Operations Per Second) are both limited and expensive when used improperly.</p><p>When Cassandra would read in data during compaction, it would read individual compressed chunks off disk, one small read at a time. Using bcc-tools, we can monitor every filesystem operation. Here I’m using <code>xfsslower</code> to record every read operation on the filesystem (original headers back in for clarity):</p><div class=\"highlight\"><pre class=\"language-shell\" data-lang=\"shell\">$ sudo /usr/share/bcc/tools/xfsslower 0 -p 26988 | awk '$4 == \"R\" { print $0 }'\nTracing XFS operations\nTIME     COMM           PID    T BYTES   OFF_KB   LAT(ms) FILENAME\n22:27:38 CompactionExec 26988  R 4096    0           0.01 nb-7-big-Statistics.db\n22:27:38 CompactionExec 26988  R 4096    4           0.00 nb-7-big-Statistics.db\n22:27:38 CompactionExec 26988  R 2062    8           0.00 nb-7-big-Statistics.db\n22:27:38 CompactionExec 26988  R 14907   0           0.01 nb-7-big-Data.db\n22:27:38 CompactionExec 26988  R 14924   14          0.01 nb-7-big-Data.db\n22:27:38 CompactionExec 26988  R 14896   29          0.01 nb-7-big-Data.db\n22:27:38 CompactionExec 26988  R 14844   43          0.01 nb-7-big-Data.db\n22:27:38 CompactionExec 26988  R 14923   58          0.01 nb-7-big-Data.db\n22:27:38 CompactionExec 26988  R 14931   72          0.01 nb-7-big-Data.db\n22:27:38 CompactionExec 26988  R 14905   87          0.01 nb-7-big-Data.db\n22:27:38 CompactionExec 26988  R 14891   101         0.01 nb-7-big-Data.db\n22:27:38 CompactionExec 26988  R 14919   116         0.01 nb-7-big-Data.db\n22:27:38 CompactionExec 26988  R 14965   130         0.01 nb-7-big-Data.db\n22:27:38 CompactionExec 26988  R 14918   145         0.01 nb-7-big-Data.db\n22:27:38 CompactionExec 26988  R 14930   160         0.01 nb-7-big-Data.db\n</pre></div><p>The above is showing we’re reading about 14KB at a time. That’s the size of the compressed page. This pattern is terrible for performance on cloud storage systems like EBS, where:</p><ol><li>Each read operation, no matter how small, counts against your provisioned IOPS</li>\n<li>Small reads waste IOPS quota while delivering minimal data</li>\n<li>You pay for IOPS allocation whether you use it efficiently or not</li>\n</ol><p>Looking at a wall clock performance profile, we can see compaction is spending a LOT of time waiting on disk, in the really wide column with the <code>pread</code> call at the top:</p><p><img src=\"https://rustyrazorblade.com/images/2025/wall-clock-profile-compaction.png\" alt=\"wall-clock-profile-compaction.png\" referrerpolicy=\"no-referrer\" /></p><p>Readahead is a disk optimization strategy where the operating system reads a larger block of data than was requested into memory. The objective is reduce latency and improve performance for sequential read operations. Unfortunately, when you don’t need the data it’s reading, it can be the source of major performance problems. In my experience, read ahead is one of the worst culprits in the world of Cassandra performance. It’s especially terrible for lightweight transactions and counters, where we perform a read before write.</p><p>My advice to Cassandra operators is to reduce readahead to 4KB to avoid unnecessary read amplification on the read path.</p><p>Readahead does have one place, however, where it can benefit performance. You <em>may</em> have already guessed that it’s compaction. Let’s take a step back and look at how the size of our reads impacts our throughput in a simple benchmark. Larger reads, initiated either from read ahead or the user, should deliver improved throughput, especially when we’re dealing with a quota on our IOPS (EBS), our drives have higher latency (SAN), or both.</p><h2 id=\"benchmarking\">Benchmarking</h2><p>I ran benchmark tests with sequential <code>fio</code> workloads using different request sizes on a 3K IOPS GP3 EBS volume. Here’s the configuration used:</p><div class=\"highlight\"><pre class=\"language-text\" data-lang=\"text\">[global]\nrw=read\ndirectory=data\ndirect=1\ntime_based=1\nfile_service_type=normal\nstonewall\nsize=100M\nnumjobs=12\ngroup_reporting\n[bs4]\nstonewall\nruntime=60s\nblocksize=4k\n[bs8]\nstonewall\nruntime=60s\nblocksize=8k\n[bs16]\nstonewall\nruntime=60s\nblocksize=16k\n[bs32]\nstonewall\nruntime=60s\nblocksize=32k\n[bs64]\nstonewall\nruntime=60s\nblocksize=64k\n[bs128]\nstonewall\nblocksize=128k\nruntime=60s\n[bs256]\nstonewall\nruntime=60s\nblocksize=256k\n</pre></div><p>When reviewing the results, the benefits of using larger request sizes were evident:</p><table><thead><tr><th>Request Size</th>\n<th>IOPS</th>\n<th>Throughput</th>\n</tr></thead><tbody><tr><td>4K</td>\n<td>3049</td>\n<td>11.9 MB/s</td>\n</tr><tr><td>8K</td>\n<td>3012</td>\n<td>23 MB/s</td>\n</tr><tr><td>16K</td>\n<td>3013</td>\n<td>47 MB/s</td>\n</tr><tr><td>32K</td>\n<td>3013</td>\n<td>94 MB/s</td>\n</tr><tr><td>64K</td>\n<td>1938</td>\n<td>121 MB/s</td>\n</tr><tr><td>128K</td>\n<td>957</td>\n<td>120 MB/s</td>\n</tr><tr><td>256K</td>\n<td>478</td>\n<td>120 MB/s</td>\n</tr></tbody></table><p>The data shows that using 256KB reads instead of 16KB reads would deliver almost 3x the throughput while using only 1/6th of the provisioned IOPS. That’s a massive efficiency improvement. Rather than chewing through all our IOPS to deliver a paltry 47MB/s of throughput, we’re only using about 500 for 120MB/s. That means if we can see these gains in the database, we’ll be able to compact faster, put more data on each node, and lower our total cost.</p><h2 id=\"the-solution-internally-buffering-sequential-reads\">The Solution: Internally Buffering Sequential Reads</h2><p>In <a href=\"https://issues.apache.org/jira/browse/CASSANDRA-15452\" target=\"_blank\">CASSANDRA-15452</a>, I worked with my fellow Cassandra committer Jordan West to implement a solution: an efficient, internal read-ahead buffer for bulk reading operations. Here’s how it works:</p><ol><li>Instead of reading tiny chunks, we use a 256KB off-heap buffer</li>\n<li>Each read operation pulls in a full 256KB of data at once</li>\n<li>Compressed chunks are extracted from this buffer as needed</li>\n<li>The buffer is refilled only when necessary</li>\n</ol><p>This approach maximizes IOPS efficiency by using larger reads during compaction (as well as repair and range reads) that deliver more data per operation. For cloud environments, it’s a game-changer that directly aligns with storage provider recommendations. AWS EBS, for instance, <a href=\"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-io-characteristics.html#ebs-io-iops\" target=\"_blank\">considers any I/O operation up to 256KB as a single operation</a>, so by using the largest possible size we should get optimal performance.</p><h2 id=\"real-world-impact-a-major-improvement-in-compaction-throughput\">Real-World Impact: A Major Improvement in Compaction Throughput</h2><p>When Jordan and I tested the implementation using <a href=\"https://github.com/rustyrazorblade/easy-cass-lab\" target=\"_blank\">easy-cass-lab</a> on EBS, the results were nothing short of spectacular. The <code>10.0.2.171</code> node is running our patched version, the other two nodes are running an unpatched release. The graphs clearly show a 2-3x improvement to throughput and a 3x reduction in IOPS.</p><p><img src=\"https://rustyrazorblade.com/images/2025/15452-bytes-read.png\" alt=\"15452-bytes-read.png\" referrerpolicy=\"no-referrer\" /></p><p><img src=\"https://rustyrazorblade.com/images/2025/15452-compaction.png\" alt=\"Compaction Throughput Comparison\" referrerpolicy=\"no-referrer\" /></p><p>You can see the results in the flamegraph as well. The calls to <code>pread</code> take up significantly less time.</p><p><img src=\"https://rustyrazorblade.com/images/2025/wall-clock-profile-compaction-after-15452.png\" alt=\"wall-clock-profile-compaction-after-15452.png\" referrerpolicy=\"no-referrer\" /></p><p>We can use <code>xfsslower</code> from <code>bcc-tools</code> again to watch the filesystem access:</p><div class=\"highlight\"><pre class=\"language-shell\" data-lang=\"shell\">$ sudo /usr/share/bcc/tools/xfsslower 0 -p $(cassandra-pid) | awk '$4 == \"R\" { print $0 }'\nTIME     COMM           PID    T BYTES   OFF_KB   LAT(ms) FILENAME\n14:40:29 CompactionExec 1782   R 262144  256         0.07 nb-4-big-Data.db\n14:40:29 CompactionExec 1782   R 262144  512         0.06 nb-4-big-Data.db\n14:40:29 CompactionExec 1782   R 262144  768         0.06 nb-4-big-Data.db\n14:40:29 CompactionExec 1782   R 262144  1024        0.07 nb-4-big-Data.db\n14:40:29 CompactionExec 1782   R 262144  1280        0.07 nb-4-big-Data.db\n14:40:29 CompactionExec 1782   R 262144  1536        0.07 nb-4-big-Data.db\n14:40:29 CompactionExec 1782   R 241123  1792        0.07 nb-4-big-Data.db\n</pre></div><p>This is a lot better, now we’re fetching 256KB at a time using way fewer requests.</p><p>The EBS test configuration used a GP3 volume with 3K IOPS and 256MB throughput. With the existing code, compaction was bottlenecked by IOPS, peaking at exactly 3K IOPS but achieving only about 51MB/s throughput. With our optimization, the same operation used only ~500 IOPS to achieve around 106MB/s—a more than 2x improvement in throughput with 1/3IOPS.</p><p>In our most aggressive testing, <strong>we actually hit the EBS throughput limit rather than the IOPS limit</strong>. That’s a significant transformation in Cassandra’s resource utilization profile.</p><p>The patch also has the benefit of applying to anti-compaction, repair, and range reads. We can see a significant reduction in range reads, aka table scans:</p><p><img src=\"https://rustyrazorblade.com/images/2025/15452-range-reads.png\" alt=\"15452-range-reads.png\" referrerpolicy=\"no-referrer\" /></p><p>If you’re running Spark jobs using the Cassandra connector, you should see an improvement in performance, and your repair times should decrease.</p><h2 id=\"whats-next--can-we-do-more\">What’s next? Can we do more?</h2><p>Yes, absolutely! There’s several more improvements to IO that will help improve things. I’ll cover them here very quickly, and if there’s interest I’ll write about them in detail in a future post.</p><h3 id=\"avoid-reading-the-statistics\">Avoid Reading the Statistics</h3><p>When compacting, we read data out of the Statistics.db file before reading the data itself. This is completely unnecessary, as it’s stats about the data we’re about to read. Skipping this can reduce IO even further. Looking at a compaction’s IO activity, I see about 30% of the filesystem access is reading from <code>Statistics.db</code>:</p><div class=\"highlight\"><pre class=\"language-text\" data-lang=\"text\">14:40:29 CompactionExec 1782   R 4096    0           0.00 nb-3-big-Statistics.db\n14:40:29 CompactionExec 1782   R 701     4           0.00 nb-3-big-Statistics.db\n14:40:29 CompactionExec 1782   R 4096    0           0.00 nb-4-big-Statistics.db\n14:40:29 CompactionExec 1782   R 4096    4           0.00 nb-4-big-Statistics.db\n14:40:29 CompactionExec 1782   R 1962    8           0.00 nb-4-big-Statistics.db\n14:40:29 CompactionExec 1782   R 262144  0           0.07 nb-4-big-Data.db\n14:40:29 CompactionExec 1782   R 2115    0           0.01 nb-3-big-Data.db\n14:40:29 CompactionExec 1782   R 262144  256         0.07 nb-4-big-Data.db\n14:40:29 CompactionExec 1782   R 262144  512         0.06 nb-4-big-Data.db\n14:40:29 CompactionExec 1782   R 262144  768         0.06 nb-4-big-Data.db\n14:40:29 CompactionExec 1782   R 262144  1024        0.07 nb-4-big-Data.db\n14:40:29 CompactionExec 1782   R 262144  1280        0.07 nb-4-big-Data.db\n14:40:29 CompactionExec 1782   R 262144  1536        0.07 nb-4-big-Data.db\n14:40:29 CompactionExec 1782   R 241123  1792        0.07 nb-4-big-Data.db\n</pre></div><p>This has already been fixed in <code>trunk</code> by Branimir Lambov in <a href=\"https://issues.apache.org/jira/browse/CASSANDRA-20092\" target=\"_blank\">CASSANDRA-20092</a> and is being backported to 5.0 by Jordan.</p><h3 id=\"direct-io-for-compaction\">Direct I/O for Compaction</h3><p>Let’s talk more about page cache. Since we go through the Linux page cache when doing reads, we want to make sure it’s working optimally. Page cache lets us avoid going to disk! Unfortunately we also use it when reading for compaction. This is a problem because we’re pulling data into the page cache that we plan on deleting. To make room for the new data, other data will be evicted. If we compact 10GB of data, we’re pushing out a lot of valuable data from the page cache, meaning it needs to be fetched back into memory later on. Using <a href=\"https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/5/html/global_file_system/s1-manage-direct-io\" target=\"_blank\">Direct I/O</a> we can bypass the page cache entirely, which will prevent data from being evicted. This can be a huge help in latency sensitive systems or systems where IOPS are limited like EBS.</p><p>I’ve filed <a href=\"https://issues.apache.org/jira/browse/CASSANDRA-19987\" target=\"_blank\">CASSANDRA-19987</a> to look at this.</p><h3 id=\"non-blocking-compression\">Non Blocking Compression</h3><p>Next, compression. When we’re writing to disk, we fill a buffer, sized by the <code>chunk_length_in_kb</code> table setting, compress, and write to disk. The compression here is a blocking call, which means we can spend a lot of time waiting on compression to finish, when we could be reading and merging the next chunk in parallel This can show up as a performance bottleneck, so I’ve filed <a href=\"https://issues.apache.org/jira/browse/CASSANDRA-20085\" target=\"_blank\">CASSANDRA-20085</a> to look into it.</p><h3 id=\"better-memory-management\">Better Memory Management</h3><p>When a system is not bottlenecked on disk I/O, such as when using NVMe, the main issue we’ll run into is our heap allocation rate. I’ll go into details in a future post, but for now, it’s enough to know that the more memory we allocate, the worse our performance. Being smart about memory allocations can make a big difference in overall time spent, as allocations aren’t free. It also reduces both the frequency and duration of Garbage Collection. Big wins all around.</p><p>I recently profiled an instance where the row size was about 2KB (not out of the ordinary) and found that a single call was accounting for roughly 50% of memory allocated. Fixing this <em>one</em> thing has the potential to deliver a massive performance improvement, especially in workloads where we have either lots of fields, or large fields like serialized blobs.</p><p>Reaching again for async-profiler, this time we run it with <code>-e alloc</code> to track allocations and <code>--reverse</code> to reverse the stacks. I do this because the same underlying call comes from the read path and compaction, and I want to see the time in aggregate.</p><p><img src=\"https://rustyrazorblade.com/images/2025/allocation-profile-compaction.png\" alt=\"allocation-profile-compaction.png\" referrerpolicy=\"no-referrer\" /></p><p>Addressing this single allocation won’t just deliver faster compaction, but will reduce pressure on the heap, which in turn reduces GC overhead. As part of this series I’ll also be covering GC, as a lot’s changed since I wrote about it last.</p><p>I’ve filed <a href=\"https://issues.apache.org/jira/browse/CASSANDRA-20428\" target=\"_blank\">CASSANDRA-20428</a> and there’s already a fair bit of discussion about different approaches to solving the problem.</p><h2 id=\"conclusion\">Conclusion</h2><p>Maximizing compaction throughput is critical for achieving higher node density with Apache Cassandra. The improvements in <a href=\"https://issues.apache.org/jira/browse/CASSANDRA-15452\" target=\"_blank\">CASSANDRA-15452</a> have removed one of the primary bottlenecks that previously limited practical node size in a lot of clusters.</p><p>By upgrading to Cassandra 5.0.4 (or later) you can:</p><ol><li>Dramatically improve compaction throughput</li>\n<li>Reduce IOPS consumption significantly</li>\n<li>Improve overall system stability during write-heavy workloads</li>\n<li>Increase the maximum practical data density per node</li>\n<li>Significantly reduce your cloud storage costs</li>\n</ol><p>This improvement, combined with the streaming optimizations discussed in the <a href=\"https://rustyrazorblade.com/post/2025/03-streaming/\">previous post</a>, creates a multiplier effect on your ability to increase node density. Each optimization removes a bottleneck, allowing you to push your hardware further and achieve more with less.</p><p>In my next post, I’ll be discussing how and why compaction strategies affect node density. Picking the right strategy can have a significant impact on your cluster’s performance and cost efficiency. Make sure you sign up for my <a href=\"https://rustyrazorblade.com/mailing-list/\">mailing list</a> if you’re interested in getting notified when it’s released!</p>If you found this post helpful, please consider sharing to your network. I'm also available to help you be successful with your distributed systems! Please<a href=\"mailto:info@rustyrazorblade.com?subject=Consulting%20Services%20Inquiry\">reach out</a>if you're interested in working with me, and I'll be happy to schedule a free one-hour consultation.","id":"716f9c80-d6d7-54c8-afdd-766f03897674","title":"Cassandra Compaction Throughput Performance Explained","origin_url":"https://rustyrazorblade.com/post/2025/04-compaction-throughput/","url":"https://rustyrazorblade.com/post/2025/04-compaction-throughput/","wallabag_created_at":"2025-04-24T12:03:02+00:00","published_at":"2025-04-16T00:00:00+00:00","published_by":"['']","reading_time":14,"domain_name":"rustyrazorblade.com","preview_picture":"https://rustyrazorblade.com/images/2025/wall-clock-profile-compaction.png","tags":["cassandra","performance"],"description":"This is the second post in my series on improving node density and lowering costs with Apache Cassandra. In the previous post, I examined how streaming performance impacts node density and operational..."},{"content":"<p dir=\"auto\">Welcome to the Awesome Accord repository! This guide provides resources and examples for implementing ACID transactions in Apache Cassandra. Learn how to leverage distributed transactions for building reliable applications.</p><ul dir=\"auto\"><li><strong>Quick Start with Docker</strong>: Single-node deployment for immediate testing</li>\n<li><strong>Lab Environment</strong>: Multi-node cluster setup for development</li>\n<li><strong>Use Cases &amp; Examples</strong>: Production-ready implementations</li>\n<li><strong>Learning Resources</strong>: Documentation and best practices</li>\n</ul><p dir=\"auto\">Accord is in active development and still a feature branch in the Apasche Cassandra® Repo. You will find bug. What we ask is that you help with a contribution of a bug report.</p><p dir=\"auto\">You can use the <a href=\"https://github.com/pmcfadin/awesome-accord/discussions\">Github discussions</a> bug report forum for this or use the Planet Cassandra Discord channel for accord listed below. A bug report should have the folowing:</p><ul dir=\"auto\"><li>The data model used</li>\n<li>Actions to reproduce the bug</li>\n<li>Full stack trace from system.log</li>\n</ul><p dir=\"auto\">If you have suggestions about syntax or improving the overall developer expirience, we want to hear about that to! Add it as a suggestion or feature request using <a href=\"https://github.com/pmcfadin/awesome-accord/discussions\">Github discussions</a> or let us know in the Planet Cassandra Discord.</p><p dir=\"auto\">Now, on to the fun!</p><div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"docker pull pmcfadin/cassandra-accord docker run -d --name cassandra-accord -p 9042:9042 pmcfadin/cassandra-accord\"><pre>docker pull pmcfadin/cassandra-accord\ndocker run -d --name cassandra-accord -p 9042:9042 pmcfadin/cassandra-accord</pre></div><div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"brew tap rustyrazorblade/rustyrazorblade brew install easy-cass-lab\"><pre>brew tap rustyrazorblade/rustyrazorblade\nbrew install easy-cass-lab</pre></div><ul dir=\"auto\"><li><strong>Banking Transactions</strong>: Account transfers with ACID guarantees</li>\n<li><strong>Inventory Management</strong>: Race-free inventory tracking</li>\n<li><strong>User Management</strong>: Multi-table atomic operations</li>\n</ul><ul dir=\"auto\"><li>Provide feedback and bug reports in the <a href=\"https://github.com/pmcfadin/awesome-accord/discussions\">repository forum</a></li>\n<li><a href=\"https://discord.gg/GrRCajJqmQ\" rel=\"nofollow\">Join our Discord Community</a> for discussions and support</li>\n<li>Review our <a href=\"https://github.com/pmcfadin/awesome-accord/blob/main/CONTRIBUTING.md\">Contributor Guide</a></li>\n<li>Submit issues and improvements through GitHub</li>\n</ul><div class=\"snippet-clipboard-content notranslate position-relative overflow-auto\" data-snippet-clipboard-copy-content=\"/ ├── docker/ # Docker configuration and setup ├── easy-cass-lab/ # Multi-node testing environment ├── examples/ # Implementation examples │ ├── banking/ # Financial transaction examples │ ├── inventory/ # Stock management examples │ └── user-mgmt/ # User operations examples └── docs/ # Guides and documentation\"><pre>/\n├── docker/              # Docker configuration and setup\n├── easy-cass-lab/      # Multi-node testing environment\n├── examples/           # Implementation examples\n│   ├── banking/       # Financial transaction examples\n│   ├── inventory/     # Stock management examples\n│   └── user-mgmt/     # User operations examples\n└── docs/              # Guides and documentation\n</pre></div><p dir=\"auto\">Our <a href=\"https://github.com/pmcfadin/awesome-accord/blob/main/docs/README.md\">documentation</a> includes:</p><ul dir=\"auto\"><li>Comprehensive setup instructions</li>\n<li>Transaction patterns and implementations</li>\n<li>Performance optimization guides</li>\n<li>Troubleshooting and best practices</li>\n</ul><ol dir=\"auto\"><li>Choose your deployment option:\n<ul dir=\"auto\"><li><a href=\"https://github.com/pmcfadin/awesome-accord/blob/main/docker/README.md\">Docker Guide</a></li>\n<li><a href=\"https://github.com/pmcfadin/awesome-accord/blob/main/easy-cass-lab/README.md\">Easy-Cass-Lab Guide</a></li>\n</ul></li>\n<li>Follow the <a href=\"https://github.com/pmcfadin/awesome-accord/blob/main/docs/quickstart.md\">Quick Start Guide</a></li>\n<li>Explore <a href=\"https://github.com/pmcfadin/awesome-accord/blob/main/examples\">example implementations</a></li>\n<li>Connect with our <a href=\"https://discord.gg/GrRCajJqmQ\" rel=\"nofollow\">Discord community</a></li>\n<li>Feedback! <a href=\"https://github.com/pmcfadin/awesome-accord/discussions\">Github Discussions</a></li>\n</ol><div class=\"highlight highlight-source-sql notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"BEGIN TRANSACTION LET fromBalance = (SELECT account_balance FROM ks.accounts WHERE account_holder='alice'); IF fromBalance.account_balance &gt;= 20 THEN UPDATE ks.accounts SET account_balance -= 20 WHERE account_holder='alice'; UPDATE ks.accounts SET account_balance += 20 WHERE account_holder='bob'; END IF COMMIT TRANSACTION;\"><pre>BEGIN TRANSACTION\n    LET fromBalance = (SELECT account_balance \n                      FROM ks.accounts \n                      WHERE account_holder='alice');\n    IF fromBalance.account_balance &gt;= 20 THEN\n        UPDATE ks.accounts \n        SET account_balance -= 20 \n        WHERE account_holder='alice';\n        UPDATE ks.accounts \n        SET account_balance += 20 \n        WHERE account_holder='bob';\n    END IF\nCOMMIT TRANSACTION;</pre></div><p dir=\"auto\">Apache License 2.0</p>","id":"19f1d3b7-37d9-5bb4-a0f6-b15fa788df22","title":"GitHub - pmcfadin/awesome-accord: Repository of all kinds of things to help you get up and running with ACID transactions on Apache Cassandra®","origin_url":"https://github.com/pmcfadin/awesome-accord","url":"https://github.com/pmcfadin/awesome-accord","wallabag_created_at":"2025-01-16T16:28:31+00:00","published_at":null,"published_by":"['pmcfadin']","reading_time":1,"domain_name":"github.com","preview_picture":"https://opengraph.githubassets.com/3e477fb2dd2b1ded1c5b53477f4848297badc75ece00c5b49bad1476fdb76167/pmcfadin/awesome-accord","tags":["acid","open.source","cassandra","accord"],"description":"Welcome to the Awesome Accord repository! This guide provides resources and examples for implementing ACID transactions in Apache Cassandra. Learn how to leverage distributed transactions for building..."},{"content":"<p dir=\"auto\">Visual Flow is an ETL tool designed for effective data manipulation via convenient and user-friendly interface. The tool has the following capabilities:</p><ul dir=\"auto\"><li>Can integrate data from heterogeneous sources:\n<ul dir=\"auto\"><li>AWS S3</li>\n<li>Cassandra</li>\n<li>Click House</li>\n<li>DB2</li>\n<li>Dataframe (for reading)</li>\n<li>Elastic Search</li>\n<li>IBM COS</li>\n<li>Kafka</li>\n<li>Local File</li>\n<li>MS SQL</li>\n<li>Mongo</li>\n<li>MySQL/Maria</li>\n<li>Oracle</li>\n<li>PostgreSQL</li>\n<li>Redis</li>\n<li>Redshift</li>\n</ul></li>\n<li>Leverage direct connectivity to enterprise applications as sources and targets</li>\n<li>Perform data processing and transformation</li>\n<li>Run custom code</li>\n<li>Leverage metadata for analysis and maintenance</li>\n</ul><p dir=\"auto\">Visual Flow application is divided into the following repositories:</p><p dir=\"auto\"><a href=\"https://github.com/ibagroup-eu/Visual-Flow/blob/main/CONTRIBUTING.md\">Check the official guide</a>.</p><p dir=\"auto\">Visual flow is an open-source software licensed under the <a href=\"https://github.com/ibagroup-eu/Visual-Flow/blob/main/LICENSE\">Apache-2.0 license</a>.</p>","id":"988e1911-975f-50b5-849a-7e9d4dd5fe35","title":"GitHub - ibagroup-eu/Visual-Flow: Visual-Flow main repository","origin_url":"https://github.com/ibagroup-eu/Visual-Flow","url":"https://github.com/ibagroup-eu/Visual-Flow","wallabag_created_at":"2024-12-02T13:34:31+00:00","published_at":null,"published_by":"['ibagroup-eu']","reading_time":null,"domain_name":"github.com","preview_picture":"https://opengraph.githubassets.com/9187fdecad3a37939c1971bcdec19ffed4090307ee508b009f47c7bcd49a7f8d/ibagroup-eu/Visual-Flow","tags":["mongo","nocode","elasticsearch","open.source","cassandra","data.pipeline","elastic","aws.s3","etl","low.code","postgres"],"description":"Visual Flow is an ETL tool designed for effective data manipulation via convenient and user-friendly interface. The tool has the following capabilities:Can integrate data from heterogeneous sources:\nA..."},{"content":"<p dir=\"auto\"><a href=\"https://github.com/datastax/cql-proxy/actions/workflows/test.yml\"><img src=\"https://github.com/datastax/cql-proxy/actions/workflows/test.yml/badge.svg\" alt=\"GitHub Action\" class=\"c13\" referrerpolicy=\"no-referrer\" /></a> <a href=\"https://goreportcard.com/report/github.com/datastax/cql-proxy\" rel=\"nofollow\"><img src=\"https://camo.githubusercontent.com/e1c32ff51117d37ba38fd853bb54c63214d25a3a367d0de90a00a03124924acb/68747470733a2f2f676f7265706f7274636172642e636f6d2f62616467652f6769746875622e636f6d2f64617461737461782f63716c2d70726f7879\" alt=\"Go Report Card\" data-canonical-src=\"https://goreportcard.com/badge/github.com/datastax/cql-proxy\" class=\"c13\" referrerpolicy=\"no-referrer\" /></a></p><p dir=\"auto\"><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/datastax/cql-proxy/blob/main/cql-proxy.png\"><img src=\"https://github.com/datastax/cql-proxy/raw/main/cql-proxy.png\" alt=\"cql-proxy\" class=\"c13\" referrerpolicy=\"no-referrer\" /></a></p><p dir=\"auto\"><code>cql-proxy</code> is designed to forward your application's CQL traffic to an appropriate database service. It listens on a local address and securely forwards that traffic.</p><p dir=\"auto\">The <code>cql-proxy</code> sidecar enables unsupported CQL drivers to work with <a href=\"https://astra.datastax.com/\" rel=\"nofollow\">DataStax Astra</a>. These drivers include both legacy DataStax <a href=\"https://docs.datastax.com/en/driver-matrix/doc/driver_matrix/common/driverMatrix.html\" rel=\"nofollow\">drivers</a> and community-maintained CQL drivers, such as the <a href=\"https://github.com/gocql/gocql\">gocql</a> driver and the <a href=\"https://github.com/scylladb/scylla-rust-driver\">rust-driver</a>.</p><p dir=\"auto\"><code>cql-proxy</code> also enables applications that are currently using <a href=\"https://cassandra.apache.org/\" rel=\"nofollow\">Apache Cassandra</a> or <a href=\"https://www.datastax.com/products/datastax-enterprise\" rel=\"nofollow\">DataStax Enterprise (DSE)</a> to use Astra without requiring any code changes. Your application just needs to be configured to use the proxy.</p><p dir=\"auto\">If you're building a new application using DataStax <a href=\"https://docs.datastax.com/en/driver-matrix/doc/driver_matrix/common/driverMatrix.html\" rel=\"nofollow\">drivers</a>, <code>cql-proxy</code> is not required, as the drivers can communicate directly with Astra. DataStax drivers have excellent support for Astra out-of-the-box, and are well-documented in the <a href=\"https://docs.datastax.com/en/astra/docs/connecting-to-astra-databases-using-datastax-drivers.html\" rel=\"nofollow\">driver-guide</a> guide.</p><p dir=\"auto\">Use the <code>-h</code> or <code>--help</code> flag to display a listing all flags and their corresponding descriptions and environment variables (shown below as items starting with <code>$</code>):</p><div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"$ ./cql-proxy -h Usage: cql-proxy Flags: -h, --help Show context-sensitive help. -b, --astra-bundle=STRING Path to secure connect bundle for an Astra database. Requires '--username' and '--password'. Ignored if using the token or contact points option ($ASTRA_BUNDLE). -t, --astra-token=STRING Token used to authenticate to an Astra database. Requires '--astra-database-id'. Ignored if using the bundle path or contact points option ($ASTRA_TOKEN). -i, --astra-database-id=STRING Database ID of the Astra database. Requires '--astra-token' ($ASTRA_DATABASE_ID) --astra-api-url=&quot;https://api.astra.datastax.com&quot; URL for the Astra API ($ASTRA_API_URL) --astra-timeout=10s Timeout for contacting Astra when retrieving the bundle and metadata ($ASTRA_TIMEOUT) -c, --contact-points=CONTACT-POINTS,... Contact points for cluster. Ignored if using the bundle path or token option ($CONTACT_POINTS). -u, --username=STRING Username to use for authentication ($USERNAME) -p, --password=STRING Password to use for authentication ($PASSWORD) -r, --port=9042 Default port to use when connecting to cluster ($PORT) -n, --protocol-version=&quot;v4&quot; Initial protocol version to use when connecting to the backend cluster (default: v4, options: v3, v4, v5, DSEv1, DSEv2) ($PROTOCOL_VERSION) -m, --max-protocol-version=&quot;v4&quot; Max protocol version supported by the backend cluster (default: v4, options: v3, v4, v5, DSEv1, DSEv2) ($MAX_PROTOCOL_VERSION) -a, --bind=&quot;:9042&quot; Address to use to bind server ($BIND) -f, --config=CONFIG YAML configuration file ($CONFIG_FILE) --debug Show debug logging ($DEBUG) --health-check Enable liveness and readiness checks ($HEALTH_CHECK) --http-bind=&quot;:8000&quot; Address to use to bind HTTP server used for health checks ($HTTP_BIND) --heartbeat-interval=30s Interval between performing heartbeats to the cluster ($HEARTBEAT_INTERVAL) --idle-timeout=60s Duration between successful heartbeats before a connection to the cluster is considered unresponsive and closed ($IDLE_TIMEOUT) --readiness-timeout=30s Duration the proxy is unable to connect to the backend cluster before it is considered not ready ($READINESS_TIMEOUT) --idempotent-graph If true it will treat all graph queries as idempotent by default and retry them automatically. It may be dangerous to retry some graph queries -- use with caution ($IDEMPOTENT_GRAPH). --num-conns=1 Number of connection to create to each node of the backend cluster ($NUM_CONNS) --proxy-cert-file=STRING Path to a PEM encoded certificate file with its intermediate certificate chain. This is used to encrypt traffic for proxy clients ($PROXY_CERT_FILE) --proxy-key-file=STRING Path to a PEM encoded private key file. This is used to encrypt traffic for proxy clients ($PROXY_KEY_FILE) --rpc-address=STRING Address to advertise in the 'system.local' table for 'rpc_address'. It must be set if configuring peer proxies ($RPC_ADDRESS) --data-center=STRING Data center to use in system tables ($DATA_CENTER) --tokens=TOKENS,... Tokens to use in the system tables. It's not recommended ($TOKENS)\"><pre>$ ./cql-proxy -h\nUsage: cql-proxy\nFlags:\n  -h, --help                                              Show context-sensitive help.\n  -b, --astra-bundle=STRING                               Path to secure connect bundle for an Astra database. Requires '--username' and '--password'. Ignored if using the\n                                                          token or contact points option ($ASTRA_BUNDLE).\n  -t, --astra-token=STRING                                Token used to authenticate to an Astra database. Requires '--astra-database-id'. Ignored if using the bundle path\n                                                          or contact points option ($ASTRA_TOKEN).\n  -i, --astra-database-id=STRING                          Database ID of the Astra database. Requires '--astra-token' ($ASTRA_DATABASE_ID)\n      --astra-api-url=\"https://api.astra.datastax.com\"    URL for the Astra API ($ASTRA_API_URL)\n      --astra-timeout=10s                                 Timeout for contacting Astra when retrieving the bundle and metadata ($ASTRA_TIMEOUT)\n  -c, --contact-points=CONTACT-POINTS,...                 Contact points for cluster. Ignored if using the bundle path or token option ($CONTACT_POINTS).\n  -u, --username=STRING                                   Username to use for authentication ($USERNAME)\n  -p, --password=STRING                                   Password to use for authentication ($PASSWORD)\n  -r, --port=9042                                         Default port to use when connecting to cluster ($PORT)\n  -n, --protocol-version=\"v4\"                             Initial protocol version to use when connecting to the backend cluster (default: v4, options: v3, v4, v5, DSEv1,\n                                                          DSEv2) ($PROTOCOL_VERSION)\n  -m, --max-protocol-version=\"v4\"                         Max protocol version supported by the backend cluster (default: v4, options: v3, v4, v5, DSEv1, DSEv2)\n                                                          ($MAX_PROTOCOL_VERSION)\n  -a, --bind=\":9042\"                                      Address to use to bind server ($BIND)\n  -f, --config=CONFIG                                     YAML configuration file ($CONFIG_FILE)\n      --debug                                             Show debug logging ($DEBUG)\n      --health-check                                      Enable liveness and readiness checks ($HEALTH_CHECK)\n      --http-bind=\":8000\"                                 Address to use to bind HTTP server used for health checks ($HTTP_BIND)\n      --heartbeat-interval=30s                            Interval between performing heartbeats to the cluster ($HEARTBEAT_INTERVAL)\n      --idle-timeout=60s                                  Duration between successful heartbeats before a connection to the cluster is considered unresponsive and closed\n                                                          ($IDLE_TIMEOUT)\n      --readiness-timeout=30s                             Duration the proxy is unable to connect to the backend cluster before it is considered not ready\n                                                          ($READINESS_TIMEOUT)\n      --idempotent-graph                                  If true it will treat all graph queries as idempotent by default and retry them automatically. It may be\n                                                          dangerous to retry some graph queries -- use with caution ($IDEMPOTENT_GRAPH).\n      --num-conns=1                                       Number of connection to create to each node of the backend cluster ($NUM_CONNS)\n      --proxy-cert-file=STRING                            Path to a PEM encoded certificate file with its intermediate certificate chain. This is used to encrypt traffic\n                                                          for proxy clients ($PROXY_CERT_FILE)\n      --proxy-key-file=STRING                             Path to a PEM encoded private key file. This is used to encrypt traffic for proxy clients ($PROXY_KEY_FILE)\n      --rpc-address=STRING                                Address to advertise in the 'system.local' table for 'rpc_address'. It must be set if configuring peer proxies\n                                                          ($RPC_ADDRESS)\n      --data-center=STRING                                Data center to use in system tables ($DATA_CENTER)\n      --tokens=TOKENS,...                                 Tokens to use in the system tables. It's not recommended ($TOKENS)</pre></div><p dir=\"auto\">To pass configuration to <code>cql-proxy</code>, either command-line flags, environment variables, or a configuration file can be used. Using the <code>docker</code> method as an example, the following samples show how the token and database ID are defined with each method.</p><div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"docker run -p 9042:9042 --rm datastax/cql-proxy:v0.1.5 --astra-token &lt;astra-token&gt; --astra-database-id &lt;astra-datbase-id&gt;\"><pre>docker run -p 9042:9042 \\\n  --rm datastax/cql-proxy:v0.1.5 \\\n  --astra-token &lt;astra-token&gt; --astra-database-id &lt;astra-datbase-id&gt;</pre></div><div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"docker run -p 9042:9042 --rm datastax/cql-proxy:v0.1.5 -e ASTRA_TOKEN=&lt;astra-token&gt; -e ASTRA_DATABASE_ID=&lt;astra-datbase-id&gt;\"><pre>docker run -p 9042:9042  \\\n  --rm datastax/cql-proxy:v0.1.5 \\\n  -e ASTRA_TOKEN=&lt;astra-token&gt; -e ASTRA_DATABASE_ID=&lt;astra-datbase-id&gt;</pre></div><p dir=\"auto\">Proxy settings can also be passed using a configuration file with the <code>--config /path/to/proxy.yaml</code> flag. This can be mixed and matched with command-line flags and environment variables. Here are some example configuration files:</p><div class=\"highlight highlight-source-yaml notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"contact-points: - 127.0.0.1 username: cassandra password: cassandra port: 9042 bind: 127.0.0.1:9042 # ...\"><pre>contact-points:\n  - 127.0.0.1\nusername: cassandra\npassword: cassandra\nport: 9042\nbind: 127.0.0.1:9042\n# ...</pre></div><p dir=\"auto\">or with a Astra token:</p><div class=\"highlight highlight-source-yaml notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"astra-token: &lt;astra-token&gt; astra-database-id: &lt;astra-database-id&gt; bind: 127.0.0.1:9042 # ...\"><pre>astra-token: &lt;astra-token&gt;\nastra-database-id: &lt;astra-database-id&gt;\nbind: 127.0.0.1:9042\n# ...</pre></div><p dir=\"auto\">All configuration keys match their command-line flag counterpart, e.g. <code>--astra-bundle</code> is <code>astra-bundle:</code>, <code>--contact-points</code> is <code>contact-points:</code> etc.</p><p dir=\"auto\">Multi-region failover with DC-aware load balancing policy is the most useful case for a multiple proxy setup.</p><p dir=\"auto\">When configuring <code>peers:</code> it is required to set <code>--rpc-address</code> (or <code>rpc-address:</code> in the yaml) for each proxy and it must match is corresponding <code>peers:</code> entry. Also, <code>peers:</code> is only available in the configuration file and cannot be set using a command-line flag.</p><p dir=\"auto\">Here's an example of configuring multi-region failover with two proxies. A proxy is started for each region of the cluster connecting to it using that region's bundle. They all share a common configuration file that contains the full list of proxies.</p><p dir=\"auto\"><em>Note:</em> Only bundles are supported for multi-region setups.</p><div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"cql-proxy --astra-bundle astra-region1-bundle.zip --username token --password &lt;astra-token&gt; --bind 127.0.0.1:9042 --rpc-address 127.0.0.1 --data-center dc-1 --config proxy.yaml\"><pre>cql-proxy --astra-bundle astra-region1-bundle.zip --username token --password &lt;astra-token&gt; \\\n  --bind 127.0.0.1:9042 --rpc-address 127.0.0.1 --data-center dc-1 --config proxy.yaml</pre></div><div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"cql-proxy ---astra-bundle astra-region2-bundle.zip --username token --password &lt;astra-token&gt; --bind 127.0.0.2:9042 --rpc-address 127.0.0.2 --data-center dc-2 --config proxy.yaml\"><pre>cql-proxy ---astra-bundle astra-region2-bundle.zip --username token --password &lt;astra-token&gt; \\\n  --bind 127.0.0.2:9042 --rpc-address 127.0.0.2 --data-center dc-2 --config proxy.yaml</pre></div><p dir=\"auto\">The peers settings are configured using a yaml file. It's a good idea to explicitly provide the <code>--data-center</code> flag, otherwise; these values are pulled from the backend cluster and would need to be pulled from the <code>system.local</code> and <code>system.peers</code> table to properly setup the peers <code>data-center:</code> values. Here's an example <code>proxy.yaml</code>:</p><div class=\"highlight highlight-source-yaml notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"peers: - rpc-address: 127.0.0.1 data-center: dc-1 - rpc-address: 127.0.0.2 data-center: dc-2\"><pre>peers:\n  - rpc-address: 127.0.0.1\n    data-center: dc-1\n  - rpc-address: 127.0.0.2\n    data-center: dc-2</pre></div><p dir=\"auto\"><em>Note:</em> It's okay for the <code>peers:</code> to contain entries for the current proxy itself because they'll just be omitted.</p><p dir=\"auto\">There are three methods for using <code>cql-proxy</code>:</p><ul dir=\"auto\"><li>Locally build and run <code>cql-proxy</code></li>\n<li>Run a docker image that has <code>cql-proxy</code> installed</li>\n<li>Use a Kubernetes container to run <code>cql-proxy</code></li>\n</ul><ol dir=\"auto\"><li>\n<p dir=\"auto\">Build <code>cql-proxy</code>.</p>\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"go build\"><pre>go build</pre></div>\n</li>\n<li>\n<p dir=\"auto\">Run with your desired database.</p>\n<ul dir=\"auto\"><li>\n<p dir=\"auto\"><a href=\"https://astra.datastax.com/\" rel=\"nofollow\">DataStax Astra</a> cluster:</p>\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"./cql-proxy --astra-token &lt;astra-token&gt; --astra-database-id &lt;astra-database-id&gt;\"><pre>./cql-proxy --astra-token &lt;astra-token&gt; --astra-database-id &lt;astra-database-id&gt;</pre></div>\n<p dir=\"auto\">The <code>&lt;astra-token&gt;</code> can be generated using these <a href=\"https://docs.datastax.com/en/astra/docs/manage-application-tokens.html\" rel=\"nofollow\">instructions</a>. The proxy also supports using the <a href=\"https://docs.datastax.com/en/astra/docs/obtaining-database-credentials.html#_getting_your_secure_connect_bundle\" rel=\"nofollow\">Astra Secure Connect Bundle</a> along with a client ID and secret generated using these <a href=\"https://docs.datastax.com/en/astra/docs/manage-application-tokens.html\" rel=\"nofollow\">instructions</a>:</p>\n<div class=\"snippet-clipboard-content notranslate position-relative overflow-auto\" data-snippet-clipboard-copy-content=\"./cql-proxy --astra-bundle &lt;your-secure-connect-zip&gt; --username &lt;astra-client-id&gt; --password &lt;astra-client-secret&gt;\"><pre>./cql-proxy --astra-bundle &lt;your-secure-connect-zip&gt; \\\n--username &lt;astra-client-id&gt; --password &lt;astra-client-secret&gt;\n</pre></div>\n</li>\n<li>\n<p dir=\"auto\"><a href=\"https://cassandra.apache.org/\" rel=\"nofollow\">Apache Cassandra</a> cluster:</p>\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"./cql-proxy --contact-points &lt;cluster node IPs or DNS names&gt; [--username &lt;username&gt;] [--password &lt;password&gt;]\"><pre>./cql-proxy --contact-points &lt;cluster node IPs or DNS names&gt; [--username &lt;username&gt;] [--password &lt;password&gt;]</pre></div>\n</li>\n</ul></li>\n</ol><ol dir=\"auto\"><li>\n<p dir=\"auto\">Run with your desired database.</p>\n<ul dir=\"auto\"><li>\n<p dir=\"auto\"><a href=\"https://astra.datastax.com/\" rel=\"nofollow\">DataStax Astra</a> cluster:</p>\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"docker run -p 9042:9042 datastax/cql-proxy:v0.1.5 --astra-token &lt;astra-token&gt; --astra-database-id &lt;astra-database-id&gt;\"><pre>docker run -p 9042:9042 \\\n  datastax/cql-proxy:v0.1.5 \\\n  --astra-token &lt;astra-token&gt; --astra-database-id &lt;astra-database-id&gt;</pre></div>\n<p dir=\"auto\">The <code>&lt;astra-token&gt;</code> can be generated using these <a href=\"https://docs.datastax.com/en/astra/docs/manage-application-tokens.html\" rel=\"nofollow\">instructions</a>. The proxy also supports using the <a href=\"https://docs.datastax.com/en/astra/docs/obtaining-database-credentials.html#_getting_your_secure_connect_bundle\" rel=\"nofollow\">Astra Secure Connect Bundle</a>, but it requires mounting the bundle to a volume in the container:</p>\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"docker run -v &lt;your-secure-connect-bundle.zip&gt;:/tmp/scb.zip -p 9042:9042 --rm datastax/cql-proxy:v0.1.5 --astra-bundle /tmp/scb.zip --username &lt;astra-client-id&gt; --password &lt;astra-client-secret&gt;\"><pre>docker run -v &lt;your-secure-connect-bundle.zip&gt;:/tmp/scb.zip -p 9042:9042 \\\n--rm datastax/cql-proxy:v0.1.5 \\\n--astra-bundle /tmp/scb.zip --username &lt;astra-client-id&gt; --password &lt;astra-client-secret&gt;</pre></div>\n</li>\n<li>\n<p dir=\"auto\"><a href=\"https://cassandra.apache.org/\" rel=\"nofollow\">Apache Cassandra</a> cluster:</p>\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"docker run -p 9042:9042 datastax/cql-proxy:v0.1.5 --contact-points &lt;cluster node IPs or DNS names&gt; [--username &lt;username&gt;] [--password &lt;password&gt;]\"><pre>docker run -p 9042:9042 \\\n  datastax/cql-proxy:v0.1.5 \\\n  --contact-points &lt;cluster node IPs or DNS names&gt; [--username &lt;username&gt;] [--password &lt;password&gt;]</pre></div>\n</li>\n</ul></li>\n</ol><p dir=\"auto\">If you wish to have the docker image removed after you are done with it, add <code>--rm</code> before the image name <code>datastax/cql-proxy:v0.1.5</code>.</p><p dir=\"auto\">Using Kubernetes with <code>cql-proxy</code> requires a number of steps:</p><ol dir=\"auto\"><li>\n<p dir=\"auto\">Generate a token following the Astra <a href=\"https://docs.datastax.com/en/astra/docs/manage-application-tokens.html#_create_application_token\" rel=\"nofollow\">instructions</a>. This step will display your Client ID, Client Secret, and Token; make sure you download the information for the next steps. Store the secure bundle in <code>/tmp/scb.zip</code> to match the example below.</p>\n</li>\n<li>\n<p dir=\"auto\">Create <code>cql-proxy.yaml</code>. You'll need to add three sets of information: arguments, volume mounts, and volumes. A full example can be found <a href=\"https://github.com/datastax/cql-proxy/blob/main/k8s/cql-proxy.yml\">here</a>.</p>\n</li>\n</ol><ul dir=\"auto\"><li>\n<p dir=\"auto\">Argument: Modify the local bundle location, username and password, using the client ID and client secret obtained in the last step to the container argument.</p>\n<div class=\"snippet-clipboard-content notranslate position-relative overflow-auto\" data-snippet-clipboard-copy-content=\"command: [&quot;./cql-proxy&quot;] args: [&quot;--astra-bundle=/tmp/scb.zip&quot;,&quot;--username=Client ID&quot;,&quot;--password=Client Secret&quot;]\"><pre>command: [\"./cql-proxy\"]\nargs: [\"--astra-bundle=/tmp/scb.zip\",\"--username=Client ID\",\"--password=Client Secret\"]\n</pre></div>\n</li>\n<li>\n<p dir=\"auto\">Volume mounts: Modify <code>/tmp/</code> as a volume mount as required.</p>\n<div class=\"snippet-clipboard-content notranslate position-relative overflow-auto\" data-snippet-clipboard-copy-content=\"volumeMounts: - name: my-cm-vol mountPath: /tmp/\"><pre>volumeMounts:\n  - name: my-cm-vol\n  mountPath: /tmp/\n</pre></div>\n</li>\n<li>\n<p dir=\"auto\">Volume: Modify the <code>configMap</code> filename as required. In this example, it is named <code>cql-proxy-configmap</code>. Use the same name for the <code>volumes</code> that you used for the <code>volumeMounts</code>.</p>\n<div class=\"snippet-clipboard-content notranslate position-relative overflow-auto\" data-snippet-clipboard-copy-content=\"volumes: - name: my-cm-vol configMap: name: cql-proxy-configmap\"><pre>volumes:\n  - name: my-cm-vol\n    configMap:\n      name: cql-proxy-configmap        \n</pre></div>\n</li>\n</ul><ol start=\"3\" dir=\"auto\"><li>\n<p dir=\"auto\">Create a configmap. Use the same secure bundle that was specified in the <code>cql-proxy.yaml</code>.</p>\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"kubectl create configmap cql-proxy-configmap --from-file /tmp/scb.zip\"><pre>kubectl create configmap cql-proxy-configmap --from-file /tmp/scb.zip </pre></div>\n</li>\n<li>\n<p dir=\"auto\">Check the configmap that was created.</p>\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"kubectl describe configmap cql-proxy-configmap Name: cql-proxy-configmap Namespace: default Labels: &lt;none&gt; Annotations: &lt;none&gt; Data ==== BinaryData ==== scb.zip: 12311 bytes\"><pre>kubectl describe configmap cql-proxy-configmap\n  Name:         cql-proxy-configmap\n  Namespace:    default\n  Labels:       &lt;none&gt;\n  Annotations:  &lt;none&gt;\n  Data\n  ====\n  BinaryData\n  ====\n  scb.zip: 12311 bytes</pre></div>\n</li>\n<li>\n<p dir=\"auto\">Create a Kubernetes deployment with the YAML file you created:</p>\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"kubectl create -f cql-proxy.yaml\"><pre>kubectl create -f cql-proxy.yaml</pre></div>\n</li>\n<li>\n<p dir=\"auto\">Check the logs:</p>\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"kubectl logs &lt;deployment-name&gt;\"><pre>kubectl logs &lt;deployment-name&gt;</pre></div>\n</li>\n</ol><p dir=\"auto\">Drivers that use token-aware load balancing may print a warning or may not work when using cql-proxy. Because cql-proxy abstracts the backend cluster as a single endpoint this doesn't always work well with token-aware drivers that expect there to be at least \"replication factor\" number of nodes in the cluster. Many drivers print a warning (which can be ignored) and fallback to something like round-robin, but other drivers might fail with an error. For the drivers that fail with an error it is required that they disable token-aware or configure the round-robin load balancing policy.</p>","id":"46e6ccfe-7ae3-5b01-9b45-db01f8f06c62","title":"GitHub - datastax/cql-proxy: A client-side CQL proxy/sidecar.","origin_url":"https://github.com/datastax/cql-proxy","url":"https://github.com/datastax/cql-proxy","wallabag_created_at":"2024-11-01T17:26:01+00:00","published_at":null,"published_by":"['datastax']","reading_time":8,"domain_name":"github.com","preview_picture":"https://opengraph.githubassets.com/c2528e3426d98910ed27819e048b4c1081fab2ed2c7adbea6e6a3b1872deb30a/datastax/cql-proxy","tags":["migration","proxy","cassandra","cql"],"description":" cql-proxy is designed to forward your application's CQL traffic to an appropriate database service. It listens on a local address and securely forwards that traffic.The cql-proxy sidecar enables unsu..."}]},{"tag":"github","articles":[{"content":"<p>A new blog post covering each of the main components of this project can be found here:</p>\n<p><a href=\"http://thelastpickle.com/blog/2018/01/23/docker-meet-cassandra.html\" rel=\"nofollow\">http://thelastpickle.com/blog/2018/01/23/docker-meet-cassandra.html</a></p>\n<div class=\"highlight highlight-source-shell\"><pre>git clone git@github.com:thelastpickle/docker-cassandra-bootstrap.git\ncd docker-cassandra-bootstrap\ncp .env.template .env\ndocker-compose build</pre></div>\n<p>If you would like to see a hosted log service interact seemlessly with this Docker Compose stack, sign up for <a href=\"https://papertrailapp.com/?thank=1ad15b\" rel=\"nofollow\">Papertrail</a>.</p>\n<p>Then find your specific port number by looking at your <a href=\"https://papertrailapp.com/account/destinations\" rel=\"nofollow\">Log Destinations</a> and update your <code>.env</code> setting accordingly.</p>\n<div class=\"highlight highlight-source-shell\"><pre># turn off all running Docker containers\ndocker-compose down\n# delete any persistent data\nrm -rf data/\n# rebuild the images\ndocker-compose build</pre></div>\n<p>Start our Docker-integrated logging connector:</p>\n<div class=\"highlight highlight-source-shell\"><pre># start Docker logging connector\ndocker-compose up logspout\n# view logging HTTP endpoint\ncurl http://localhost:8000/logs</pre></div>\n<p>Start Cassandra and setup the required schema:</p>\n<div class=\"highlight highlight-source-shell\"><pre># start Cassandra\ndocker-compose up cassandra\n# view cluster status\ndocker-compose run nodetool status\n# create schema\ndocker-compose run cqlsh -f /schema.cql\n# confirm schema\ndocker-compose run cqlsh -e \"DESCRIBE SCHEMA;\"</pre></div>\n<p>Start Reaper for Apache Cassandra and monitor your new cluster:</p>\n<div class=\"highlight highlight-source-shell\"><pre># start Reaper for Apache Cassandra\ndocker-compose up cassandra-reaper\nopen http://localhost:8080/webui/\n# add one-off repair\n# add scheduled repair</pre></div>\n<p>Start Prometheus and become familiar with the UI:</p>\n<div class=\"highlight highlight-source-shell\"><pre># start Prometheus\ndocker-compose up prometheus\nopen http://localhost:9090</pre></div>\n<p>Start Grafana, connect it to the Prometheus data source, and upload the TLP Dashboards.</p>\n<div class=\"highlight highlight-source-shell\"><pre># start Grafana\ndocker-compose up grafana\n# create \n./grafana/bin/create-data-sources.sh\n# user/pass: admin/admin\nopen http://localhost:3000\n# upload dashboards\n./grafana/bin/upload-dashboards.sh</pre></div>\n<p>Generate fake workforce and activity:</p>\n<div class=\"highlight highlight-source-shell\"><pre>docker-compose run pickle-factory</pre></div>\n<p>Sample timesheets:</p>\n<div class=\"highlight highlight-source-shell\"><pre>docker-compose run pickle-shop</pre></div>","id":"f950326f-a534-5983-9f77-7ebbc14f932b","title":"thelastpickle/docker-cassandra-bootstrap","origin_url":"https://github.com/thelastpickle/docker-cassandra-bootstrap","url":"https://github.com/thelastpickle/docker-cassandra-bootstrap","wallabag_created_at":"2018-05-25T21:15:40+00:00","published_at":null,"published_by":"['']","reading_time":1,"domain_name":"github.com","preview_picture":"https://opengraph.githubassets.com/3e8c3c57c7b7abfb9ce896d1ccf7a27ce34b383eec2d79d3b8ffc4ab6ef4ffef/thelastpickle/docker-cassandra-bootstrap","tags":["cassandra","github","docker"],"description":"A new blog post covering each of the main components of this project can be found here:\nhttp://thelastpickle.com/blog/2018/01/23/docker-meet-cassandra.html\ngit clone git@github.com:thelastpickle/docke..."},{"content":"<h2>Theory of Operation</h2><p>Tablesnap is a script that uses inotify to monitor a directory for <code>IN_MOVED_TO</code>\nevents and reacts to them by spawning a new thread to upload that file to\nAmazon S3, along with a JSON-formatted list of what other files were in the\ndirectory at the time of the copy.</p><p>When running a Cassandra cluster, this behavior can be quite useful as it\nallows for automated point-in-time backups of SSTables. Theoretically,\ntablesnap should work for any application where files are written to some\ntemporary location, then moved into their final location once the data is\nwritten to disk. Tablesnap also makes the assumption that files are immutable\nonce written.</p><h2>Installation</h2><p>The simplest way to install tablesnap is from the Python Package Index, PyPI.\n<a href=\"https://pypi.python.org/pypi/tablesnap\" rel=\"nofollow\">https://pypi.python.org/pypi/tablesnap</a></p><pre>pip install tablesnap\n</pre><p>This distribution provides a debian/ source directory, allowing it to be built\nas a standard Debian/Ubuntu package and stored in a repository. The Debian\npackage includes an init script that can run and daemonize tablesnap for you.\nTablesnap does not daemonize itself. This is best left to tools like\ninit, supervisord, daemontools, etc.</p><p>We do not currently maintain binary packages of tablesnap. To build the debian\npackage from source, assuming you have a working pbuilder environment:</p><pre>git checkout debian\ngit-buildpackage --git-upstream-branch=master --git-debian-branch=debian --git-builder='pdebuild'\n</pre><p>The daemonized version of the Debian/Ubuntu package uses syslog for logging.\nThe messages are sent to the <code>DAEMON</code> logging facility and tagged with\n<code>tablesnap</code>. If you want to redirect the log output to a log file other than\n<code>/var/log/daemon.log</code> you can filter by this tag. E.g. if you are using\nsyslog-ng you could add</p><pre># tablesnap\nfilter f_tablesnap { filter(f_daemon) and match(\"tablesnap\" value(\"PROGRAM\")); };\ndestination d_tablesnap { file(\"/var/log/tablesnap.log\"); };\nlog { source(s_src); filter(f_tablesnap); destination(d_tablesnap); flags(final); };\n</pre><p>to <code>/etc/syslog-ng/syslog-ng.conf</code>.</p><p>If you are not a Debian/Ubuntu user or do not wish to install the tablesnap\npackage, you may copy the tablesnap script anywhere you'd like and run it from\nthere. Tablesnap depends on the pyinotify and boto Python packages. These are\navailable via \"pip install pyinotify; pip install boto;\", or as packages from\nmost common Linux distributions.</p><h2>Configuration</h2><p>All configuration for tablesnap happens on the command line. If you are using\nthe Debian package, you'll set these options in the <code>DAEMON_OPTS</code> variable in\n<code>/etc/default/tablesnap</code>.</p><pre>usage: tablesnap [-h] -k AWS_KEY -s AWS_SECRET [-r] [-a] [-B] [-p PREFIX]\n                 [--without-index] [--keyname-separator KEYNAME_SEPARATOR]\n                 [-t THREADS] [-n NAME] [-e EXCLUDE | -i INCLUDE]\n                 [--listen-events {IN_MOVED_TO,IN_CLOSE_WRITE}]\n                 [--max-upload-size MAX_UPLOAD_SIZE]\n                 [--multipart-chunk-size MULTIPART_CHUNK_SIZE]\n                 bucket paths [paths ...]\nTablesnap is a script that uses inotify to monitor a directory for events and\nreacts to them by spawning a new thread to upload that file to Amazon S3,\nalong with a JSON-formatted list of what other files were in the directory at\nthe time of the copy.\npositional arguments:\n  bucket                S3 bucket\n  paths                 Paths to be watched\noptional arguments:\n  -h, --help            show this help message and exit\n  -k AWS_KEY, --aws-key AWS_KEY\n  -s AWS_SECRET, --aws-secret AWS_SECRET\n  -r, --recursive       Recursively watch the given path(s)s for new SSTables\n  -a, --auto-add        Automatically start watching new subdirectories within\n                        path(s)\n  -B, --backup          Backup existing files to S3 if they are not already\n                        there\n  -p PREFIX, --prefix PREFIX\n                        Set a string prefix for uploaded files in S3\n  --without-index       Do not store a JSON representation of the current\n                        directory listing in S3 when uploading a file to S3.\n  --keyname-separator KEYNAME_SEPARATOR\n                        Separator for the keyname between name and path.\n  -t THREADS, --threads THREADS\n                        Number of writer threads\n  -n NAME, --name NAME  Use this name instead of the FQDN to identify the\n                        files from this host\n  -e EXCLUDE, --exclude EXCLUDE\n                        Exclude files matching this regular expression from\n                        upload.WARNING: If neither exclude nor include are\n                        defined, then all files matching \"-tmp\" are excluded.\n  -i INCLUDE, --include INCLUDE\n                        Include only files matching this regular expression\n                        into upload.WARNING: If neither exclude nor include\n                        are defined, then all files matching \"-tmp\" are\n                        excluded.\n  --listen-events {IN_MOVED_TO,IN_CLOSE_WRITE,IN_CREATE}\n                        Which events to listen on, can be specified multiple\n                        times. Values: IN_MOVED_TO, IN_CLOSE_WRITE, IN_CREATE\n                        (default: IN_MOVED_TO, IN_CLOSE_WRITE)\n  --max-upload-size MAX_UPLOAD_SIZE\n                        Max size for files to be uploaded before doing\n                        multipart (default 5120M)\n  --multipart-chunk-size MULTIPART_CHUNK_SIZE\n                        Chunk size for multipart uploads (default: 256M or 10%\n                        of free memory if default is not available)\n</pre><p>For example:</p><pre>$ tablesnap -k AAAAAAAAAAAAAAAA -s BBBBBBBBBBBBBBBB me.synack.sstables /var/lib/cassandra/data/GiantKeyspace\n</pre><p>This would cause tablesnap to use the given Amazon Web Services credentials to\nbackup the SSTables for my <code>GiantKeyspace</code> to the S3 bucket named\n<code>me.synack.sstables</code>.</p><h2>Questions, Comments, and Help</h2><p>The fine folks in <code>#cassandra-ops</code> on <code>irc.freenode.net</code> are an excellent\nresource for getting tablesnap up and running, and also for solving more\ngeneral Cassandra issues.</p>","id":"cd740b21-3dd8-5171-abb4-4e789c17dbd9","title":"JeremyGrosser/tablesnap","origin_url":"https://github.com/JeremyGrosser/tablesnap","url":"https://github.com/JeremyGrosser/tablesnap","wallabag_created_at":"2018-04-03T23:50:04+00:00","published_at":null,"published_by":"['']","reading_time":4,"domain_name":"github.com","preview_picture":"https://opengraph.githubassets.com/8f43224982503de627f3b471708d935faa34ee4b6e58bb53b81a9ce7d0c66e7d/JeremyGrosser/tablesnap","tags":["aws","cassandra","github"],"description":"Theory of OperationTablesnap is a script that uses inotify to monitor a directory for IN_MOVED_TO\nevents and reacts to them by spawning a new thread to upload that file to\nAmazon S3, along with a JSON..."},{"content":"<h3>\n      \n      README.md\n    </h3><article class=\"markdown-body entry-content\" itemprop=\"text\">\n<p>A reference application for Node.js developers looking to learn more about using\n<a href=\"http://cassandra.apache.org/\" rel=\"nofollow\">Apache Cassandra</a> and <a href=\"http://www.datastax.com/products/datastax-enterprise\" rel=\"nofollow\">DataStax Enterprise</a> in their applications and\nservices. Learn more at <a href=\"https://killrvideo.github.io/\" rel=\"nofollow\">killrvideo.github.io</a>.</p>\n<h2><a id=\"user-content-running-locally\" class=\"anchor\" aria-hidden=\"true\" href=\"#running-locally\"></a>Running Locally</h2>\n<p>Use these guides to get started running KillrVideo locally on your development machine:</p>\n<ul><li><a href=\"https://killrvideo.github.io/getting-started/\" rel=\"nofollow\">Getting Started with KillrVideo</a>: Follow this to setup common dependencies\nlike Docker.</li>\n<li><a href=\"https://killrvideo.github.io/docs/languages/nodejs/\" rel=\"nofollow\">Getting Started with Node.js</a>: Follow this to get this Node.js code\nrunning.</li>\n</ul><h2><a id=\"user-content-contributing-requests-for-more-examples\" class=\"anchor\" aria-hidden=\"true\" href=\"#contributing-requests-for-more-examples\"></a>Contributing, Requests for More Examples</h2>\n<p>This project will continue to evolve along with Cassandra and you can expect that as\nCassandra, DSE, and the drivers add new features, this application will try and provide\nexamples of those.  We gladly accept any pull requests for bug fixes, new features, etc. and\nif you have a request for an example that you don't see in the code currently, feel free to\nopen an issue here on GitHub or send a message to <a href=\"https://twitter.com/LukeTillman\" rel=\"nofollow\">@LukeTillman</a> on Twitter.</p>\n</article>","id":"fc49c54e-9796-516d-85ef-2f0b661c8bca","title":"KillrVideo/killrvideo-nodejs","origin_url":"https://github.com/KillrVideo/killrvideo-nodejs","url":"https://github.com/KillrVideo/killrvideo-nodejs","wallabag_created_at":"2018-03-14T22:27:46+00:00","published_at":null,"published_by":null,"reading_time":null,"domain_name":"github.com","preview_picture":"https://opengraph.githubassets.com/4f50ab463beb119ee95e16cec253627bc046097a770ec753fa46bdf8a735602a/KillrVideo/killrvideo-nodejs","tags":["cassandra","node","github"],"description":"\n      \n      README.md\n    \nA reference application for Node.js developers looking to learn more about using\nApache Cassandra and DataStax Enterprise in their applications and\nservices. Learn more at..."},{"content":"<h3>\n      \n      README.md\n    </h3><article class=\"markdown-body entry-content\" itemprop=\"text\">\n<p>A reference application for .NET developers looking to learn more about using <a href=\"http://cassandra.apache.org/\" rel=\"nofollow\">Apache Cassandra</a> and\n<a href=\"http://www.datastax.com/products/datastax-enterprise\" rel=\"nofollow\">DataStax Enterprise</a> in their applications and services. Learn more at <a href=\"https://killrvideo.github.io/\" rel=\"nofollow\">killrvideo.github.io</a>.</p>\n<h2><a href=\"#running-locally\" aria-hidden=\"true\" class=\"anchor\" id=\"user-content-running-locally\"></a>Running Locally</h2>\n<p>Use these guides to get started running KillrVideo locally on your development machine:</p>\n<ul><li><a href=\"https://killrvideo.github.io/getting-started/\" rel=\"nofollow\">Getting Started with KillrVideo</a>: Follow this to setup common dependencies like Docker.</li>\n<li><a href=\"https://killrvideo.github.io/docs/languages/c-sharp/\" rel=\"nofollow\">Getting Started with C#</a>: Follow this to get this C# code running.</li>\n</ul><h2><a href=\"#pull-requests-requests-for-more-examples\" aria-hidden=\"true\" class=\"anchor\" id=\"user-content-pull-requests-requests-for-more-examples\"></a>Pull Requests, Requests for More Examples</h2>\n<p>This project will continue to evolve along with Cassandra and you can expect that as Cassandra and the DataStax driver add new features, this sample application will try and provide examples of those.  I'll gladly accept any pull requests for bug fixes, new features, etc.  and if you have a request for an example that you don't see in the code currently, send me a message <a href=\"https://twitter.com/LukeTillman\" rel=\"nofollow\">@LukeTillman</a> on Twitter or open an issue here on GitHub.</p>\n<h2><a href=\"#license\" aria-hidden=\"true\" class=\"anchor\" id=\"user-content-license\"></a>License</h2>\n<p>Copyright 2016 Luke Tillman</p>\n<p>Licensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at</p>\n<p><a href=\"http://www.apache.org/licenses/LICENSE-2.0\" rel=\"nofollow\">http://www.apache.org/licenses/LICENSE-2.0</a></p>\n<p>Unless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.</p>\n</article>","id":"59f4ae26-bf0e-54ce-ba3a-d90e00ea31ad","title":"LukeTillman/killrvideo-csharp","origin_url":"https://github.com/LukeTillman/killrvideo-csharp","url":"https://github.com/LukeTillman/killrvideo-csharp","wallabag_created_at":"2018-03-14T22:27:36+00:00","published_at":null,"published_by":null,"reading_time":1,"domain_name":"github.com","preview_picture":"https://opengraph.githubassets.com/c1cf548592976495837a26647aae2acf25f30bf82d0d7271025a6fae57195cea/LukeTillman/killrvideo-csharp","tags":["cassandra","csharp","github"],"description":"\n      \n      README.md\n    \nA reference application for .NET developers looking to learn more about using Apache Cassandra and\nDataStax Enterprise in their applications and services. Learn more at ki..."}]},{"tag":"testing","articles":[{"content":"<div data-pjax-replace=\"\" id=\"js-flash-container\"><div class=\"flash flash-full {{ className }} px-2\"><p>{{ message }}</p></div>\n</div><div class=\"application-main\" data-commit-hovercards-enabled=\"\" data-discussion-hovercards-enabled=\"\" data-issue-and-pr-hovercards-enabled=\"\"><main id=\"js-repo-pjax-container\" data-pjax-container=\"\"><div id=\"repository-container-header\" class=\"pt-3 hide-full-screen c3\" data-pjax-replace=\"\"><div class=\"d-flex mb-3 px-3 px-md-4 px-lg-5\"><p> / <strong itemprop=\"name\" class=\"mr-2 flex-self-stretch\"><a data-pjax=\"#repo-content-pjax-container\" href=\"https://github.com/apache/cassandra-harry\">cassandra-harry</a></strong> Public</p><ul class=\"pagehead-actions flex-shrink-0 d-none d-md-inline c1\"><li><a href=\"https://github.com/login?return_to=%2Fapache%2Fcassandra-harry\" rel=\"nofollow\" data-hydro-click=\"{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;notification subscription menu watch&quot;,&quot;repository_id&quot;:null,&quot;auth_type&quot;:&quot;LOG_IN&quot;,&quot;originating_url&quot;:&quot;https://github.com/apache/cassandra-harry&quot;,&quot;user_id&quot;:null}}\" data-hydro-click-hmac=\"9cf17cf30bb042224fd5877004d34f4e99e95f6488041ba1ea9a11a0bab36f47\" aria-label=\"You must be signed in to change notification settings\" data-view-component=\"true\" class=\"tooltipped tooltipped-s btn-sm btn\">Notifications</a></li>\n<li><a href=\"https://github.com/login?return_to=%2Fapache%2Fcassandra-harry\" rel=\"nofollow\" data-hydro-click=\"{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;repo details fork button&quot;,&quot;repository_id&quot;:292627306,&quot;auth_type&quot;:&quot;LOG_IN&quot;,&quot;originating_url&quot;:&quot;https://github.com/apache/cassandra-harry&quot;,&quot;user_id&quot;:null}}\" data-hydro-click-hmac=\"16cc71ae0543724bd3934f99a05d0a8a4c0dad8342599c07e6c15e6e968b5552\" aria-label=\"You must be signed in to fork a repository\" data-view-component=\"true\" class=\"tooltipped tooltipped-s btn-sm btn\">Fork 12</a></li>\n<li>\n<p><a href=\"https://github.com/login?return_to=%2Fapache%2Fcassandra-harry\" rel=\"nofollow\" data-hydro-click=\"{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;star button&quot;,&quot;repository_id&quot;:292627306,&quot;auth_type&quot;:&quot;LOG_IN&quot;,&quot;originating_url&quot;:&quot;https://github.com/apache/cassandra-harry&quot;,&quot;user_id&quot;:null}}\" data-hydro-click-hmac=\"f371aced4cf7d947b7473514455df8a59812332fa68e0591cfbcbabb5876773e\" aria-label=\"You must be signed in to star a repository\" data-view-component=\"true\" class=\"tooltipped tooltipped-s btn-sm btn BtnGroup-item\"> Star 43</a> </p>\n</li>\n</ul></div><div class=\"d-block d-md-none mb-2 px-3 px-md-4 px-lg-5\" id=\"responsive-meta-container\" data-pjax-replace=\"\"><p class=\"f4 mb-3\">Apache Cassandra - Harry</p><p><a title=\"https://cassandra.apache.org/\" role=\"link\" target=\"_blank\" class=\"text-bold\" rel=\"noopener noreferrer\" href=\"https://cassandra.apache.org/\">cassandra.apache.org/</a></p><h3 class=\"sr-only\">License</h3><p><a href=\"https://github.com/apache/cassandra-harry/blob/trunk/LICENSE.txt\" class=\"Link--muted\" data-analytics-event=\"{&quot;category&quot;:&quot;Repository Overview&quot;,&quot;action&quot;:&quot;click&quot;,&quot;label&quot;:&quot;location:sidebar;file:license&quot;}\"> Apache-2.0 license</a></p><p><a class=\"Link--secondary no-underline mr-3\" href=\"https://github.com/apache/cassandra-harry/stargazers\"> 43 stars</a> <a class=\"Link--secondary no-underline\" href=\"https://github.com/apache/cassandra-harry/network/members\"> 12 forks</a></p><div class=\"d-flex\"><p><a href=\"https://github.com/login?return_to=%2Fapache%2Fcassandra-harry\" rel=\"nofollow\" data-hydro-click=\"{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;star button&quot;,&quot;repository_id&quot;:292627306,&quot;auth_type&quot;:&quot;LOG_IN&quot;,&quot;originating_url&quot;:&quot;https://github.com/apache/cassandra-harry&quot;,&quot;user_id&quot;:null}}\" data-hydro-click-hmac=\"f371aced4cf7d947b7473514455df8a59812332fa68e0591cfbcbabb5876773e\" aria-label=\"You must be signed in to star a repository\" data-view-component=\"true\" class=\"tooltipped tooltipped-s btn-sm btn btn-block BtnGroup-item\"> Star</a> </p><p><a href=\"https://github.com/login?return_to=%2Fapache%2Fcassandra-harry\" rel=\"nofollow\" data-hydro-click=\"{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;notification subscription menu watch&quot;,&quot;repository_id&quot;:null,&quot;auth_type&quot;:&quot;LOG_IN&quot;,&quot;originating_url&quot;:&quot;https://github.com/apache/cassandra-harry&quot;,&quot;user_id&quot;:null}}\" data-hydro-click-hmac=\"9cf17cf30bb042224fd5877004d34f4e99e95f6488041ba1ea9a11a0bab36f47\" aria-label=\"You must be signed in to change notification settings\" data-view-component=\"true\" class=\"tooltipped tooltipped-s btn-sm btn btn-block\">Notifications</a></p></div></div></div>\n</main></div>\n<footer class=\"footer width-full container-xl p-responsive\" role=\"contentinfo\"><div class=\"position-relative d-flex flex-items-center pb-2 f6 color-fg-muted border-top color-border-muted flex-column-reverse flex-lg-row flex-wrap flex-lg-nowrap mt-6 pt-6\"><ul class=\"list-style-none d-flex flex-wrap col-0 col-lg-2 flex-justify-start flex-lg-justify-between mb-2 mb-lg-0\"><li class=\"mt-2 mt-lg-0 d-flex flex-items-center\"> © 2022 GitHub, Inc.</li>\n</ul></div>\n</footer><p> You can’t perform that action at this time.</p>\n<p> You signed in with another tab or window. <a href=\"\">Reload</a> to refresh your session. You signed out in another tab or window. <a href=\"\">Reload</a> to refresh your session.</p>\n<details class=\"details-reset details-overlay details-overlay-dark lh-default color-fg-default hx_rsm\" open=\"open\">\n\n</details>","id":"166bfd43-cfec-506b-be68-f384b93820b4","title":"GitHub - apache/cassandra-harry: Apache Cassandra - Harry","origin_url":"https://github.com/apache/cassandra-harry","url":"https://github.com/apache/cassandra-harry","wallabag_created_at":"2022-06-08T20:37:16+00:00","published_at":null,"published_by":"['apache']","reading_time":null,"domain_name":"github.com","preview_picture":"https://opengraph.githubassets.com/aa15162e4aac1bfa5fbd58f2757de131eaa602ad2bc71025321e6eeb66ff4553/apache/cassandra-harry","tags":["cassandra","testing"],"description":"{{ message }}\n / cassandra-harry PublicNotifications\nFork 12\n\n Star 43 \n\nApache Cassandra - Harrycassandra.apache.org/License Apache-2.0 license 43 stars  12 forks Star Notifications\n\n © 2022 GitHub, ..."},{"content":"<div class=\"flash flash-full {{ className }} px-2\" data-pjax-replace=\"\" id=\"js-flash-container\"><p>{{ message }}</p></div>\n<div class=\"application-main\" data-commit-hovercards-enabled=\"\" data-discussion-hovercards-enabled=\"\" data-issue-and-pr-hovercards-enabled=\"\"><main id=\"js-repo-pjax-container\" data-pjax-container=\"\"><div id=\"repository-container-header\" class=\"pt-3 hide-full-screen c3\" data-pjax-replace=\"\"><div class=\"d-block d-md-none mb-2 px-3 px-md-4 px-lg-5\" id=\"responsive-meta-container\" data-pjax-replace=\"\"><p class=\"f4 mb-3\">Apache cassandra diff</p><p><a title=\"https://cassandra.apache.org/\" role=\"link\" target=\"_blank\" class=\"text-bold\" rel=\"noopener noreferrer\" href=\"https://cassandra.apache.org/\">cassandra.apache.org/</a></p><h3 class=\"sr-only\">License</h3><p><a href=\"https://github.com/apache/cassandra-diff/blob/trunk/LICENSE.txt\" class=\"Link--muted\" data-analytics-event=\"{&quot;category&quot;:&quot;Repository Overview&quot;,&quot;action&quot;:&quot;click&quot;,&quot;label&quot;:&quot;location:sidebar;file:license&quot;}\">Apache-2.0 license</a></p><p><a class=\"Link--secondary no-underline mr-3\" href=\"https://github.com/apache/cassandra-diff/stargazers\">10 stars</a> <a class=\"Link--secondary no-underline\" href=\"https://github.com/apache/cassandra-diff/network/members\">16 forks</a></p></div></div>\n</main></div>\n<footer class=\"footer width-full container-xl p-responsive\" role=\"contentinfo\"><div class=\"position-relative d-flex flex-items-center pb-2 f6 color-fg-muted border-top color-border-muted flex-column-reverse flex-lg-row flex-wrap flex-lg-nowrap mt-6 pt-6\"><ul class=\"list-style-none d-flex flex-wrap col-0 col-lg-2 flex-justify-start flex-lg-justify-between mb-2 mb-lg-0\"><li class=\"mt-2 mt-lg-0 d-flex flex-items-center\">© 2022 GitHub, Inc.</li>\n</ul></div>\n</footer><p>You can’t perform that action at this time.</p>\n<p>You signed in with another tab or window. <a href=\"\">Reload</a> to refresh your session. You signed out in another tab or window. <a href=\"\">Reload</a> to refresh your session.</p>\n<details class=\"details-reset details-overlay details-overlay-dark lh-default color-fg-default hx_rsm\" open=\"open\"></details>","id":"d29b900a-7c3e-537e-a25e-6c8caff38e03","title":"GitHub - apache/cassandra-diff: Apache cassandra diff","origin_url":"https://github.com/apache/cassandra-diff","url":"https://github.com/apache/cassandra-diff","wallabag_created_at":"2022-06-08T20:37:07+00:00","published_at":null,"published_by":"['']","reading_time":null,"domain_name":"github.com","preview_picture":"https://opengraph.githubassets.com/e7a10c615cc491e34c4e3f952c02c227c9b02a49ab4ccf2ebd3bc5832f285203/apache/cassandra-diff","tags":["cassandra","testing"],"description":"{{ message }}\nApache cassandra diffcassandra.apache.org/LicenseApache-2.0 license10 stars 16 forks\n\n© 2022 GitHub, Inc.\n\nYou can’t perform that action at this time.\nYou signed in with another tab or w..."},{"content":"<div data-pjax-replace=\"\" id=\"js-flash-container\"><div class=\"flash flash-full {{ className }} px-2\"><p>{{ message }}</p></div>\n</div><div class=\"application-main\" data-commit-hovercards-enabled=\"\" data-discussion-hovercards-enabled=\"\" data-issue-and-pr-hovercards-enabled=\"\"><main id=\"js-repo-pjax-container\" data-pjax-container=\"\"><div id=\"repository-container-header\" class=\"pt-3 hide-full-screen c3\" data-pjax-replace=\"\"><div class=\"d-flex mb-3 px-3 px-md-4 px-lg-5\"><p> / <strong itemprop=\"name\" class=\"mr-2 flex-self-stretch\"><a data-pjax=\"#repo-content-pjax-container\" href=\"https://github.com/datastax/adelphi\">adelphi</a></strong> Public</p><ul class=\"pagehead-actions flex-shrink-0 d-none d-md-inline c1\"><li><a href=\"https://github.com/login?return_to=%2Fdatastax%2Fadelphi\" rel=\"nofollow\" data-hydro-click=\"{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;notification subscription menu watch&quot;,&quot;repository_id&quot;:null,&quot;auth_type&quot;:&quot;LOG_IN&quot;,&quot;originating_url&quot;:&quot;https://github.com/datastax/adelphi&quot;,&quot;user_id&quot;:null}}\" data-hydro-click-hmac=\"dd7eb365e4b5d3f98a22bdd8d18a4af0fbd166a0491e1f620c51d20d647aec28\" aria-label=\"You must be signed in to change notification settings\" data-view-component=\"true\" class=\"tooltipped tooltipped-s btn-sm btn\">Notifications</a></li>\n<li><a href=\"https://github.com/login?return_to=%2Fdatastax%2Fadelphi\" rel=\"nofollow\" data-hydro-click=\"{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;repo details fork button&quot;,&quot;repository_id&quot;:280185818,&quot;auth_type&quot;:&quot;LOG_IN&quot;,&quot;originating_url&quot;:&quot;https://github.com/datastax/adelphi&quot;,&quot;user_id&quot;:null}}\" data-hydro-click-hmac=\"1997e3a5189659d5f9c924425df984a1798c6158f289de62ec3cf960385f554d\" aria-label=\"You must be signed in to fork a repository\" data-view-component=\"true\" class=\"tooltipped tooltipped-s btn-sm btn\">Fork 4</a></li>\n<li>\n<p><a href=\"https://github.com/login?return_to=%2Fdatastax%2Fadelphi\" rel=\"nofollow\" data-hydro-click=\"{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;star button&quot;,&quot;repository_id&quot;:280185818,&quot;auth_type&quot;:&quot;LOG_IN&quot;,&quot;originating_url&quot;:&quot;https://github.com/datastax/adelphi&quot;,&quot;user_id&quot;:null}}\" data-hydro-click-hmac=\"f054bc7eba043e2fe1b97fb786319ed96ea23960ae6311a7994628481c32ae93\" aria-label=\"You must be signed in to star a repository\" data-view-component=\"true\" class=\"tooltipped tooltipped-s btn-sm btn BtnGroup-item\"> Star 9</a> </p>\n</li>\n</ul></div><div class=\"d-block d-md-none mb-2 px-3 px-md-4 px-lg-5\" id=\"responsive-meta-container\" data-pjax-replace=\"\"><p class=\"f4 mb-3\">Automation tool for testing C* OSS that assembles cassandra-diff, nosqlbench, fqltool</p><h3 class=\"sr-only\">License</h3><p><a href=\"https://github.com/datastax/adelphi/blob/master/LICENSE.txt\" class=\"Link--muted\" data-analytics-event=\"{&quot;category&quot;:&quot;Repository Overview&quot;,&quot;action&quot;:&quot;click&quot;,&quot;label&quot;:&quot;location:sidebar;file:license&quot;}\"> Apache-2.0 license</a></p><p><a class=\"Link--secondary no-underline mr-3\" href=\"https://github.com/datastax/adelphi/stargazers\"> 9 stars</a> <a class=\"Link--secondary no-underline\" href=\"https://github.com/datastax/adelphi/network/members\"> 4 forks</a></p><div class=\"d-flex\"><p><a href=\"https://github.com/login?return_to=%2Fdatastax%2Fadelphi\" rel=\"nofollow\" data-hydro-click=\"{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;star button&quot;,&quot;repository_id&quot;:280185818,&quot;auth_type&quot;:&quot;LOG_IN&quot;,&quot;originating_url&quot;:&quot;https://github.com/datastax/adelphi&quot;,&quot;user_id&quot;:null}}\" data-hydro-click-hmac=\"f054bc7eba043e2fe1b97fb786319ed96ea23960ae6311a7994628481c32ae93\" aria-label=\"You must be signed in to star a repository\" data-view-component=\"true\" class=\"tooltipped tooltipped-s btn-sm btn btn-block BtnGroup-item\"> Star</a> </p><p><a href=\"https://github.com/login?return_to=%2Fdatastax%2Fadelphi\" rel=\"nofollow\" data-hydro-click=\"{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;notification subscription menu watch&quot;,&quot;repository_id&quot;:null,&quot;auth_type&quot;:&quot;LOG_IN&quot;,&quot;originating_url&quot;:&quot;https://github.com/datastax/adelphi&quot;,&quot;user_id&quot;:null}}\" data-hydro-click-hmac=\"dd7eb365e4b5d3f98a22bdd8d18a4af0fbd166a0491e1f620c51d20d647aec28\" aria-label=\"You must be signed in to change notification settings\" data-view-component=\"true\" class=\"tooltipped tooltipped-s btn-sm btn btn-block\">Notifications</a></p></div></div></div>\n</main></div>\n<footer class=\"footer width-full container-xl p-responsive\" role=\"contentinfo\"><div class=\"position-relative d-flex flex-items-center pb-2 f6 color-fg-muted border-top color-border-muted flex-column-reverse flex-lg-row flex-wrap flex-lg-nowrap mt-6 pt-6\"><ul class=\"list-style-none d-flex flex-wrap col-0 col-lg-2 flex-justify-start flex-lg-justify-between mb-2 mb-lg-0\"><li class=\"mt-2 mt-lg-0 d-flex flex-items-center\"> © 2022 GitHub, Inc.</li>\n</ul></div>\n</footer><p> You can’t perform that action at this time.</p>\n<p> You signed in with another tab or window. <a href=\"\">Reload</a> to refresh your session. You signed out in another tab or window. <a href=\"\">Reload</a> to refresh your session.</p>\n<details class=\"details-reset details-overlay details-overlay-dark lh-default color-fg-default hx_rsm\" open=\"open\">\n\n</details>","id":"75fb8bf0-c48c-58d3-b5ef-b60dc7508eb1","title":"GitHub - datastax/adelphi: Automation tool for testing C* OSS that assembles cassandra-diff, nosqlbench, fqltool","origin_url":"https://github.com/datastax/adelphi","url":"https://github.com/datastax/adelphi","wallabag_created_at":"2022-06-08T20:36:15+00:00","published_at":null,"published_by":"['datastax']","reading_time":null,"domain_name":"github.com","preview_picture":"https://opengraph.githubassets.com/afe20d0322f42c980557122f254ed0db1a89239e8a1e4130618ed630ed786ddc/datastax-archive/adelphi","tags":["stress","cassandra","cassandra.stress","testing"],"description":"{{ message }}\n / adelphi PublicNotifications\nFork 4\n\n Star 9 \n\nAutomation tool for testing C* OSS that assembles cassandra-diff, nosqlbench, fqltoolLicense Apache-2.0 license 9 stars  4 forks Star Not..."},{"content":"<article class=\"markdown-body entry-content\" itemprop=\"text\">\n<p>This is a sample code of utilizing <a href=\"https://gatling.io/\" rel=\"nofollow\">Gatling</a> testing framework for stress testing with DSE</p>\n<h3><a id=\"user-content-pre-requisites\" class=\"anchor\" aria-hidden=\"true\" href=\"#pre-requisites\"></a>Pre-requisites</h3>\n<p>Note: At the moment, the latest version of Gatling framework is 2.3.1. However, the CQL plugin 0.0.7 is not compatible with Gatling 2.3.1 yet.</p>\n<ol><li>Gatling high charts bundle version 2.2.5:</li>\n</ol><ul><li><a href=\"https://repo1.maven.org/maven2/io/gatling/highcharts/gatling-charts-highcharts-bundle/2.2.5/\" rel=\"nofollow\">https://repo1.maven.org/maven2/io/gatling/highcharts/gatling-charts-highcharts-bundle/2.2.5/</a></li>\n</ul><ol start=\"2\"><li>Gatling CQL plugin v0.0.7 (latest version as of writing)</li>\n</ol><p><strong>[NOTES]</strong> - as of April 10, 2018, Gatling CQL plugin has released version 0.0.8 which works with the latest Gatling framework 2.3.1. Please feel free to download these latest versions for your test. Please also be aware that Gatling 2.3.1 requires scala 2.1.2 and make sure your scala version is upgraded first.</p>\n<h3><a id=\"user-content-notes-about-the-example-simulation-scenario\" class=\"anchor\" aria-hidden=\"true\" href=\"#notes-about-the-example-simulation-scenario\"></a>Notes about the Example Simulation Scenario</h3>\n<p>The simulation scenario (MyTestSimu.scala) as included in this example simulates a mixed read/write workload. The core steps of the scenario are summarized below and you can follow the same steps when creating your own scenario:</p>\n<ol><li>Set up connection to Cassandra/DSE cluster with proper properties, such as \"contact points\", \"load balancing policy\", etc.</li>\n<li>Create the application keyspace and table schema</li>\n<li>Define the (random) value generator for table columns based on their types</li>\n<li>Define the Read/Write statements to be used in the simulation, including the Consistency Level associated with the statements</li>\n<li>Set up the user simulation behavior for Read and Write. The key parts include:</li>\n</ol><ul><li>How many concurrent users (can be constant or some variance) to be simulated per second.</li>\n<li>How long does the simulation executes</li>\n</ul><h3><a id=\"user-content-procedure\" class=\"anchor\" aria-hidden=\"true\" href=\"#procedure\"></a>Procedure</h3>\n<ol><li>Set up Gatling framework and the CQL plug-in (just unzip, as per description found <a href=\"https://github.com/gatling-cql/GatlingCql\">here</a>)</li>\n<li>Download the MyTestSimu.scala file and put it under folder &lt;GATLING_HOME&gt;/user-files/simulations/</li>\n<li>Execute the Gatling simulation (stress-testing) scenario by running command: &lt;GATLING_HOME&gt;/bin/gatling.sh. Follow the instructions on the command-line output.</li>\n</ol><p>NOTE: The simulation scenario (MyTestSimu.scala) is tested against a DSE cluster (version 5.1.6) with UserName/Password authentication. Please adjust accordingly for your case.</p>\n<hr /><p>An example is as below. Simulation number 1 is the Cassandra stres-testing scenario as defined by this example.</p>\n<pre>$ bin/gatling.sh\nGATLING_HOME is set to /home/automaton/gatling-charts-highcharts-bundle-2.2.5\nChoose a simulation number:\n     [0] cassandra.CassandraSimulation\n     [1] cassandra.MyTestSimu\n     [2] computerdatabase.BasicSimulation\n     [3] computerdatabase.advanced.AdvancedSimulationStep01\n     [4] computerdatabase.advanced.AdvancedSimulationStep02\n     [5] computerdatabase.advanced.AdvancedSimulationStep03\n     [6] computerdatabase.advanced.AdvancedSimulationStep04\n     [7] computerdatabase.advanced.AdvancedSimulationStep05\n1\nSelect simulation id (default is 'mytestsimu'). Accepted characters are a-z, A-Z, 0-9, - and _\nSelect run description (optional)\nSimulation cassandra.MyTestSimu started...\n================================================================================\n2018-04-04 15:33:43                                           5s elapsed\n---- Requests ------------------------------------------------------------------\n&gt; Global                                                   (OK=232    KO=0     )\n&gt; upsertStmt                                               (OK=93     KO=0     )\n&gt; readStmt                                                 (OK=139    KO=0     )\n---- Read Workload Scenario ----------------------------------------------------\n[#                                                                         ]  1%\n          waiting: 8861   / active: 0      / done:139\n---- Write Workload Scenario ---------------------------------------------------\n[                                                                          ]  0%\n          waiting: 20907  / active: 0      / done:93\n================================================================================\n... ...\n================================================================================\n2018-04-04 15:43:39                                         600s elapsed\n---- Requests ------------------------------------------------------------------\n&gt; Global                                                   (OK=30000  KO=0     )\n&gt; upsertStmt                                               (OK=21000  KO=0     )\n&gt; readStmt                                                 (OK=9000   KO=0     )\n---- Read Workload Scenario ----------------------------------------------------\n[##########################################################################]100%\n          waiting: 0      / active: 0      / done:9000\n---- Write Workload Scenario ---------------------------------------------------\n[##########################################################################]100%\n          waiting: 0      / active: 0      / done:21000\n================================================================================\nSimulation cassandra.MyTestSimu completed in 600 seconds\nParsing log file(s)...\nParsing log file(s) done\nGenerating reports...\n================================================================================\n---- Global Information --------------------------------------------------------\n&gt; request count                                      30000 (OK=30000  KO=0     )\n&gt; min response time                                      0 (OK=0      KO=-     )\n&gt; max response time                                    224 (OK=224    KO=-     )\n&gt; mean response time                                     2 (OK=2      KO=-     )\n&gt; std deviation                                          5 (OK=5      KO=-     )\n&gt; response time 50th percentile                          1 (OK=1      KO=-     )\n&gt; response time 75th percentile                          2 (OK=2      KO=-     )\n&gt; response time 95th percentile                          3 (OK=3      KO=-     )\n&gt; response time 99th percentile                          7 (OK=7      KO=-     )\n&gt; mean requests/sec                                     50 (OK=50     KO=-     )\n---- Response Time Distribution ------------------------------------------------\n&gt; t &lt; 800 ms                                         30000 (100%)\n&gt; 800 ms &lt; t &lt; 1200 ms                                   0 (  0%)\n&gt; t &gt; 1200 ms                                            0 (  0%)\n&gt; failed                                                 0 (  0%)\n================================================================================\nReports generated in 4s.\nPlease open the following file: /home/automaton/gatling-charts-highcharts-bundle-2.2.5/results/mytestsimu-1522856018600/index.html\n</pre>\n</article>","id":"22b64c72-6b88-5842-8e08-ebff60cc319b","title":"yabinmeng/cassgatling","origin_url":"https://github.com/yabinmeng/cassgatling","url":"https://github.com/yabinmeng/cassgatling","wallabag_created_at":"2018-11-14T17:34:32+00:00","published_at":null,"published_by":null,"reading_time":3,"domain_name":"github.com","preview_picture":"https://opengraph.githubassets.com/ba96401352e04a099abef2d795d350d978caf9070e2f7cf302b70025f16fcffd/yabinmeng/cassgatling","tags":["stress","cassandra","gatling","testing"],"description":"\nThis is a sample code of utilizing Gatling testing framework for stress testing with DSE\nPre-requisites\nNote: At the moment, the latest version of Gatling framework is 2.3.1. However, the CQL plugin ..."}]}]}},"staticQueryHashes":[]}