{"componentChunkName":"component---src-templates-tags-js","path":"/tags/proxy/1","result":{"pageContext":{"tag":"proxy","urlTag":"proxy","chunk":[{"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":"515fda8f-d1a1-5d7c-bfc6-6d72984fb6c1","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..."},{"content":"<header>\n</header><p>Zero Downtime Migration (ZDM) Proxy is an open-source component developed in Go and based on client-server architecture. It enables you to migrate from one Apache Cassandra® cluster to another without downtime or code changes in the application client.</p><p>For details on ZDM Proxy, see <a href=\"https://github.com/datastax/zdm-proxy\" target=\"_blank\" rel=\"noopener noreferrer\">zdm-proxy GitHub</a>.</p><p>When using ZDM Proxy, the client connects to the proxy rather than to the source cluster. The proxy connects both to the source cluster and the target cluster. It sends read requests to the source cluster only, while write requests are forwarded to both clusters.</p><p>For details on how ZDM Proxy works, see <a href=\"https://docs.datastax.com/en/data-migration/introduction.html\" target=\"_blank\" rel=\"noopener noreferrer\">Introduction to Zero Downtime Migration</a>.</p><ul><li>Apache Cassandra instance to migrate to the Aiven platform (migration source)</li>\n<li>Aiven for Apache Cassandra service where to migrate your external instance (migration target)</li>\n<li><a href=\"https://aiven.io/docs/tools/cli\">Aiven CLI client installed</a></li>\n<li><code>cqlsh</code> <a href=\"https://cassandra.apache.org/doc/latest/cassandra/getting_started/installing.html\" target=\"_blank\" rel=\"noopener noreferrer\">installed</a></li>\n</ul><p><a href=\"https://aiven.io/docs/products/cassandra/howto/connect-cqlsh-cli\">Connect to your Aiven for Apache Cassandra service</a> using <code>cqlsh</code>, for example.</p><div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block codeBlockContent_biex c3\"><pre class=\"codeBlockLines_e6Vv\">cqlsh --ssl-u avnadmin -p YOUR_SECRET_PASSWORD cassandra-target-cluster-name.a.avns.net 12345<br /></pre></div><p>You can expect to receive output similar to the following:</p><div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block codeBlockContent_biex c3\"><pre class=\"codeBlockLines_e6Vv\">Connected to a1b2c3d4-1a2b-3c4d-5e6f-a1b2c3d4e5f6 at cassandra-target-cluster-name.a.avns.net:12345<br />[cqlsh 6.1.0 | Cassandra 4.0.11 | CQL spec 3.4.5 | Native protocol v5]<br /></pre></div><p>In your target service, create the same keyspaces and tables you have in your source Apache Cassandra cluster.</p><div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block codeBlockContent_biex c3\"><pre class=\"codeBlockLines_e6Vv\">create keyspace KEYSPACE_NAME with replication ={'class':'SimpleStrategy', 'replication_factor':3};<br />create table KEYSPACE_NAME.TABLE_NAME (n_id int, value int, primary key (n_id));<br /></pre></div><p>Download the ZDM Proxy's binary from <a href=\"https://github.com/datastax/zdm-proxy/releases\" target=\"_blank\" rel=\"noopener noreferrer\">ZDM Proxy releases</a>.</p><div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block codeBlockContent_biex c3\"><pre class=\"codeBlockLines_e6Vv\">wget https://github.com/datastax/zdm-proxy/releases/download/v2.1.0/zdm-proxy-linux-amd64-v2.1.0.tgz<br />tar xf zdm-proxy-linux-amd64-v2.1.0.tgz<br /></pre></div><p>Check if the binary has been downloaded successfully using <code>ls</code> in the relevant directory. You can expect to receive output similar to the following:</p><div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block codeBlockContent_biex c3\"><pre class=\"codeBlockLines_e6Vv\">LICENSE  zdm-proxy-linux-amd64-v2.1.0.tgz  zdm-proxy-v2.1.0<br /></pre></div><ol><li>\n<p>Specify connection information by setting <code>ZDM_TARGET_*</code> and <code>ZDM_ORIGIN_*</code> environment variables using the <code>export</code> command.</p>\n<div class=\"theme-admonition theme-admonition-note admonition_xJq3 alert alert--secondary\"><p>note</p><div class=\"admonitionContent_BuS1\"><p><code>ORIGIN</code> refers to the source service.</p></div></div>\n</li>\n<li>\n<p>Run the binary.</p>\n</li>\n</ol><div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block codeBlockContent_biex c3\"><pre class=\"codeBlockLines_e6Vv\">exportZDM_ORIGIN_CONTACT_POINTS=localhost<br />exportZDM_ORIGIN_USERNAME=cassandra<br />exportZDM_ORIGIN_PASSWORD=cassandra<br />exportZDM_ORIGIN_PORT=1234<br />exportZDM_TARGET_CONTACT_POINTS=cassandra-target-cluster-name.a.avns.net<br />exportZDM_TARGET_USERNAME=avnadmin<br />exportZDM_TARGET_PASSWORD=YOUR_SECRET_PASSWORD<br />exportZDM_TARGET_PORT=12345<br />exportZDM_TARGET_TLS_SERVER_CA_PATH=\"/tmp/ca.pem\"<br />exportZDM_TARGET_ENABLE_HOST_ASSIGNMENT=false<br /># ZDM_ORIGIN_ENABLE_HOST_ASSIGNMENT=false  # (may be needed, see note)<br />./zdm-proxy-v2.1.0<br /></pre></div><div class=\"theme-admonition theme-admonition-note admonition_xJq3 alert alert--secondary\"><p>ENABLE_HOST_ASSIGNMENT</p><div class=\"admonitionContent_BuS1\"><p>Make sure you set the ZDM_TARGET_ENABLE_HOST_ASSIGNMENT variable. Otherwise, ZDM Proxy tries to connect to one of internal addresses of the cluster nodes, which are unavailable from outside. If this occurs to your source cluster, set <code>ZDM_ORIGIN_ENABLE_HOST_ASSIGNMENT=false</code>.</p></div></div><p>To connect to ZDM Proxy, use, for example, <code>cqlsh</code>. Provide connection details and, if your source or target require authentication, specify target username and password.</p><p>Check more details on using the credentials in <a href=\"https://docs.datastax.com/en/data-migration/introduction.html\" target=\"_blank\" rel=\"noopener noreferrer\">Client application credentials</a>.</p><p>The port that ZDM Proxy uses is 14002, which can be overridden.</p><ol><li>\n<p>Connect using ZDM Proxy.</p>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block codeBlockContent_biex c3\"><pre class=\"codeBlockLines_e6Vv\">cqlsh -u avnadmin -p YOUR_SECRET_PASSWORD localhost 14002<br /></pre></div>\n<p>You can expect to receive output similar to the following:</p>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block codeBlockContent_biex c3\"><pre class=\"codeBlockLines_e6Vv\">Connected to CLUSTER_NAME at localhost:14002<br />[cqlsh 6.1.0 | Cassandra 4.1.3 | CQL spec 3.4.6 | Native protocol v4]<br /></pre></div>\n</li>\n<li>\n<p>Check data in the table.</p>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block codeBlockContent_biex c3\"><pre class=\"codeBlockLines_e6Vv\">select * from KEYSPACE_NAME.TABLE_NAME;<br /></pre></div>\n<p>You can expect to receive output similar to the following:</p>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block codeBlockContent_biex c3\"><pre class=\"codeBlockLines_e6Vv\">n_id | value<br />------+-------<br />1|42<br />2|44<br />3|46<br />(3 rows)<br /></pre></div>\n</li>\n<li>\n<p>Insert more data into the table to test how ZDM Proxy handles write request.</p>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block codeBlockContent_biex c3\"><pre class=\"codeBlockLines_e6Vv\">insert into KEYSPACE_NAME.TABLE_NAME (n_id, value) values (4, 48);<br />insert into KEYSPACE_NAME.TABLE_NAME (n_id, value) values (5, 50);<br /></pre></div>\n</li>\n<li>\n<p>Check again data inside the table.</p>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block codeBlockContent_biex c3\"><pre class=\"codeBlockLines_e6Vv\">select * from KEYSPACE_NAME.TABLE_NAME;<br /></pre></div>\n<p>You can expect to receive output similar to the following:</p>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block codeBlockContent_biex c3\"><pre class=\"codeBlockLines_e6Vv\">n_id | value<br />------+-------<br />5|50<br />1|42<br />2|44<br />4|48<br />3|46<br />(5 rows)<br /></pre></div>\n</li>\n</ol><ol><li>\n<p>Connect to the source:</p>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block codeBlockContent_biex c3\"><pre class=\"codeBlockLines_e6Vv\">cqlsh localhost 1234<br /></pre></div>\n<p>You can expect to receive output similar to the following:</p>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block codeBlockContent_biex c3\"><pre class=\"codeBlockLines_e6Vv\">Connected to SOURCE_CLUSTER_NAME at localhost:1234<br />[cqlsh 6.1.0 | Cassandra 4.1.3 | CQL spec 3.4.6 | Native protocol v5]<br /></pre></div>\n</li>\n<li>\n<p>Check data in the table:</p>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block codeBlockContent_biex c3\"><pre class=\"codeBlockLines_e6Vv\">select * from KEYSPACE_NAME.TABLE_NAME;<br /></pre></div>\n<p>You can expect to receive output similar to the following:</p>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block codeBlockContent_biex c3\"><pre class=\"codeBlockLines_e6Vv\">n_id | value<br />------+-------<br />5|50<br />1|42<br />2|44<br />4|48<br />3|46<br />(5 rows)<br /></pre></div>\n<p>ZDM Proxy has forwarded both the write request and the read request to the source cluster. As a result, all the values are there: both newly-added ones (<code>50</code> and <code>48</code>) and previously added ones (<code>42</code>, <code>44</code>, and <code>46</code>).</p>\n</li>\n</ol><ol><li>\n<p>Connect to the target service.</p>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block codeBlockContent_biex c3\"><pre class=\"codeBlockLines_e6Vv\">cqlsh --ssl-u avnadmin -p YOUR_SECRET_PASSWORD cassandra-target-cluster-name.a.avns.net 12345<br /></pre></div>\n<p>You can expect to receive output similar to the following:</p>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block codeBlockContent_biex c3\"><pre class=\"codeBlockLines_e6Vv\">Connected to a1b2c3d4-1a2b-3c4d-5e6f-a1b2c3d4e5f6 at cassandra-target-cluster-name.a.avns.net:12345<br />[cqlsh 6.1.0 | Cassandra 4.0.11 | CQL spec 3.4.5 | Native protocol v5]<br /></pre></div>\n</li>\n<li>\n<p>Check data in the table.</p>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block codeBlockContent_biex c3\"><pre class=\"codeBlockLines_e6Vv\">select * from KEYSPACE_NAME.TABLE_NAME;<br /></pre></div>\n<p>You can expect to receive output similar to the following:</p>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block codeBlockContent_biex c3\"><pre class=\"codeBlockLines_e6Vv\">n_id | value<br />------+-------<br />5|50<br />4|48<br />(2 rows)<br /></pre></div>\n<p><code>50</code> and <code>48</code> are there in the target table since ZDM Proxy has forwarded the write request to the target service. <code>42</code>, <code>44</code>, and <code>46</code> are not there since ZDM Proxy has not sent the read request to the target service.</p>\n</li>\n</ol><ul><li><a href=\"https://github.com/datastax/zdm-proxy\" target=\"_blank\" rel=\"noopener noreferrer\">zdm-proxy GitHub</a></li>\n<li><a href=\"https://docs.datastax.com/en/data-migration/introduction.html\" target=\"_blank\" rel=\"noopener noreferrer\">Introduction to Zero Downtime Migration</a></li>\n<li><a href=\"https://github.com/datastax/zdm-proxy/releases\" target=\"_blank\" rel=\"noopener noreferrer\">ZDM Proxy releases</a></li>\n<li><a href=\"https://docs.datastax.com/en/data-migration/connect-clients-to-target.html\" target=\"_blank\" rel=\"noopener noreferrer\">Client application credentials</a></li>\n</ul>","id":"c5cf2b78-00ff-560c-a008-3227fd0643b3","title":"Migrate to Aiven for Apache Cassandra® with no downtime | Aiven docs","origin_url":"https://aiven.io/docs/products/cassandra/howto/zdm-proxy","url":"https://aiven.io/docs/products/cassandra/howto/zdm-proxy","wallabag_created_at":"2024-11-01T17:25:08+00:00","published_at":null,"published_by":null,"reading_time":4,"domain_name":"aiven.io","preview_picture":"https://aiven.io/docs/images/site-preview.png","tags":["migration","proxy","cassandra","aiven"],"description":"\nZero Downtime Migration (ZDM) Proxy is an open-source component developed in Go and based on client-server architecture. It enables you to migrate from one Apache Cassandra® cluster to another withou..."},{"content":"<p dir=\"auto\">The ZDM Proxy is client-server component written in Go that enables users to migrate with zero downtime from an Apache Cassandra® cluster to another (which may be an <a href=\"https://astra.datastax.com/\" rel=\"nofollow\">Astra</a> cluster) and not requiring code changes in the application client.</p><p dir=\"auto\">The only change to the client is pointing it to the proxy rather than directly to the original cluster (Origin). In turn, the proxy connects to both Origin and Target clusters.</p><p dir=\"auto\">By default, the proxy will forward read requests only to the Origin cluster, though you can optionally configure it to forward reads to both clusters asynchronously, while writes will always be sent to both clusters concurrently.</p><p dir=\"auto\">An overview of the proxy architecture and logical flow can be viewed <a href=\"https://docs.datastax.com/en/data-migration/introduction.html#migration-phases\" rel=\"nofollow\">here</a>.</p><p dir=\"auto\">In order to run the proxy, you'll need to set some environment variables or pass reference to YAML configuration file. Below you'll find a list with the most important variables along with their default values. The required ones are marked with a comment. Variable names for YAML configuration file do not have <code>ZDM_</code> prefix and are lower-cased.</p><div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"ZDM_ORIGIN_CONTACT_POINTS=10.0.0.1 #required ZDM_ORIGIN_USERNAME=cassandra #required ZDM_ORIGIN_PASSWORD=cassandra #required ZDM_ORIGIN_PORT=9042 ZDM_TARGET_CONTACT_POINTS=10.0.0.2 #required ZDM_TARGET_USERNAME=cassandra #required ZDM_TARGET_PASSWORD=cassandra #required ZDM_TARGET_PORT=9042 ZDM_PROXY_LISTEN_PORT=14002 ZDM_PROXY_LISTEN_ADDRESS=127.0.0.1 ZDM_PRIMARY_CLUSTER=ORIGIN ZDM_READ_MODE=PRIMARY_ONLY ZDM_LOG_LEVEL=INFO\"><pre>ZDM_ORIGIN_CONTACT_POINTS=10.0.0.1  #required\nZDM_ORIGIN_USERNAME=cassandra       #required\nZDM_ORIGIN_PASSWORD=cassandra       #required\nZDM_ORIGIN_PORT=9042\nZDM_TARGET_CONTACT_POINTS=10.0.0.2  #required\nZDM_TARGET_USERNAME=cassandra       #required\nZDM_TARGET_PASSWORD=cassandra       #required\nZDM_TARGET_PORT=9042\nZDM_PROXY_LISTEN_PORT=14002\nZDM_PROXY_LISTEN_ADDRESS=127.0.0.1\nZDM_PRIMARY_CLUSTER=ORIGIN\nZDM_READ_MODE=PRIMARY_ONLY\nZDM_LOG_LEVEL=INFO</pre></div><p dir=\"auto\">The environment variables (or YAM configuration file) must be set for the proxy to work.</p><p dir=\"auto\">In order to get started quickly, in your local environment, grab a copy of the binary distribution in the <a href=\"https://github.com/datastax/zdm-proxy/releases\">Releases</a> page. For the recommended installation in a production environment, check the <a href=\"https://github.com/datastax/zdm-proxy#production-setup\">Production Setup</a> section below.</p><p dir=\"auto\">Now, suppose you have two clusters running at <code>10.0.0.1</code> and <code>10.0.0.2</code> with <code>cassandra/cassandra</code> credentials and the same key-value <a href=\"https://github.com/datastax/zdm-proxy/blob/main/nb-tests/schema.cql\">schema</a>. You can start the proxy and connect it to these clusters like this:</p><div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"$ export ZDM_ORIGIN_CONTACT_POINTS=10.0.0.1 \\ export ZDM_TARGET_CONTACT_POINTS=10.0.0.2 export ZDM_ORIGIN_USERNAME=cassandra export ZDM_ORIGIN_PASSWORD=cassandra export ZDM_TARGET_USERNAME=cassandra export ZDM_TARGET_PASSWORD=cassandra ./zdm-proxy-v2.0.0 # run the ZDM proxy executable\"><pre>$ export ZDM_ORIGIN_CONTACT_POINTS=10.0.0.1 \\ \nexport ZDM_TARGET_CONTACT_POINTS=10.0.0.2 \\\nexport ZDM_ORIGIN_USERNAME=cassandra \\\nexport ZDM_ORIGIN_PASSWORD=cassandra \\\nexport ZDM_TARGET_USERNAME=cassandra \\\nexport ZDM_TARGET_PASSWORD=cassandra \\\n./zdm-proxy-v2.0.0 # run the ZDM proxy executable</pre></div><p dir=\"auto\">If you prefer to use YAML configuration file, an equivalent setup would look like:</p><div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"$ cat zdm-config.yml origin_contact_points: 10.0.0.1 target_contact_points: 10.0.0.2 origin_username: cassandra origin_password: cassandra target_username: cassandra target_password: cassandra $ ./zdm-proxy-v2.0.0 --config=./zdm-config.yml # run the ZDM proxy executable\"><pre>$ cat zdm-config.yml\norigin_contact_points: 10.0.0.1\ntarget_contact_points: 10.0.0.2\norigin_username: cassandra\norigin_password: cassandra\ntarget_username: cassandra\ntarget_password: cassandra\n$ ./zdm-proxy-v2.0.0 --config=./zdm-config.yml # run the ZDM proxy executable</pre></div><p dir=\"auto\">At this point, you should be able to connect some client such as <a href=\"https://downloads.datastax.com/#cqlsh\" rel=\"nofollow\">CQLSH</a> to the proxy and write data to it and the proxy will take care of forwarding the requests to both clusters concurrently.</p><div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"$ cqlsh &lt;proxy-ip-address&gt; 14002 # this is the proxy's default listen port\"><pre>$ cqlsh &lt;proxy-ip-address&gt; 14002 # this is the proxy's default listen port</pre></div><p dir=\"auto\">From the CQLSH prompt:</p><div class=\"highlight highlight-source-sql notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"cqlsh&gt; INSERT INTO test.keyvalue (key, value) VALUES (1, 'ABC'); cqlsh&gt; INSERT INTO test.keyvalue (key, value) VALUES (2, 'DEF'); cqlsh&gt; SELECT * FROM test.keyvalue; cqlsh&gt; UPDATE test.keyvalue SET value='GYEKJF' WHERE key = 1; cqlsh&gt; DELETE FROM test.keyvalue WHERE key = 2;\"><pre>cqlsh&gt; INSERT INTO test.keyvalue (key, value) VALUES (1, 'ABC');\ncqlsh&gt; INSERT INTO test.keyvalue (key, value) VALUES (2, 'DEF');\ncqlsh&gt; SELECT * FROM test.keyvalue;\ncqlsh&gt; UPDATE test.keyvalue SET value='GYEKJF' WHERE key = 1;\ncqlsh&gt; DELETE FROM test.keyvalue WHERE key = 2;</pre></div><p dir=\"auto\">You can confirm that the data is stored in both clusters by querying them directly in other cqlsh sessions.</p><p dir=\"auto\">Note: For the moment, the keyspace must be specified when accessing a table, even after using <code>USE &lt;keyspace&gt;</code>.</p><p dir=\"auto\">If you don't have test clusters readily available to try with, check the <a href=\"https://github.com/datastax/zdm-proxy/blob/main/CONTRIBUTING.md#running-on-localhost-with-docker-compose\">alternative</a> method with docker-compose in the <a href=\"https://github.com/datastax/zdm-proxy/blob/main/CONTRIBUTING.md\">Contributor's guide</a>, which will set up all the dependencies, including two test clusters and a proxy instance, in a containerized sandbox environment.</p><p dir=\"auto\"><strong>ZDM Proxy supports protocol versions v2, v3, v4, DSE_V1 and DSE_V2.</strong></p><p dir=\"auto\">It technically doesn't support v5, but handles protocol negotiation so that the client application properly downgrades the protocol version to v4 if v5 is requested. This means that any client application using a recent driver that supports protocol version v5 can be migrated using the ZDM Proxy (as long as it does not use v5-specific functionality).</p><p dir=\"auto\">ZDM Proxy requires origin and target clusters to have at least one protocol version in common. It is therefore not feasible to configure Apache Cassandra 2.0 as origin and 3.x / 4.x as target. Below table displays protocol versions supported by various C* versions:</p><table><thead><tr><th>Apache Cassandra</th>\n<th>Protocol Version</th>\n</tr></thead><tbody><tr><td>2.0</td>\n<td>V2</td>\n</tr><tr><td>2.1</td>\n<td>V2, V3</td>\n</tr><tr><td>2.2</td>\n<td>V2, V3, V4</td>\n</tr><tr><td>3.x</td>\n<td>V3, V4</td>\n</tr><tr><td>4.x</td>\n<td>V3, V4, V5</td>\n</tr></tbody></table><hr /><p dir=\"auto\">⚠️ <strong>Thrift is not supported by ZDM Proxy.</strong> If you are using a very old driver or cluster version that only supports Thrift then you need to change your client application to use CQL and potentially upgrade your cluster before starting the migration process.</p><hr /><p dir=\"auto\">In practice this means that ZDM Proxy supports the following cluster versions (as Origin and / or Target):</p><ul dir=\"auto\"><li>Apache Cassandra from 2.0+ up to (and including) Apache Cassandra 4.x. (although both clusters have to support a common protocol version as mentioned above).</li>\n<li>DataStax Enterprise 4.8+. DataStax Enterprise 4.6 and 4.7 support will be introduced when protocol version v2 is supported.</li>\n<li>DataStax Astra DB (both Serverless and Classic)</li>\n</ul><p dir=\"auto\">The setup we described above is only for testing in a local environment. It is <strong>NOT</strong> recommended for a production installation where the minimum number of proxy instances is 3.</p><p dir=\"auto\">For a comprehensive guide with the recommended production setup check the documentation available at <a href=\"https://docs.datastax.com/en/astra-serverless/docs/migrate/introduction.html\" rel=\"nofollow\">Datastax Migration</a>.</p><p dir=\"auto\">There you'll find information about an Ansible-based tool that automates most of the process.</p><p dir=\"auto\">For information on the packaged dependencies of the Zero Downtime Migration (ZDM) Proxy and their licenses, check out our <a href=\"https://app.fossa.com/reports/ccfe72e5-68ea-4c02-ad48-d92061e6d0b0\" rel=\"nofollow\">open source report</a>.</p><p dir=\"auto\">For frequently asked questions, please refer to our separate <a href=\"https://docs.datastax.com/en/astra-serverless/docs/migrate/faqs.html\" rel=\"nofollow\">FAQ</a> page.</p>","id":"b5e34283-1bc1-59b3-890c-c53a44c6cf98","title":"GitHub - datastax/zdm-proxy: An open-source component designed to seamlessly handle the real-time client application activity while a migration is in progress.","origin_url":"https://github.com/datastax/zdm-proxy","url":"https://github.com/datastax/zdm-proxy","wallabag_created_at":"2024-11-01T17:23:20+00:00","published_at":null,"published_by":"['datastax']","reading_time":4,"domain_name":"github.com","preview_picture":"https://opengraph.githubassets.com/2d9ec70e3a53cb00af12aa2c8f6c9f9568324cfe693483d667268c95dc17d22b/datastax/zdm-proxy","tags":["migration","proxy","datastax","cassandra"],"description":"The ZDM Proxy is client-server component written in Go that enables users to migrate with zero downtime from an Apache Cassandra® cluster to another (which may be an Astra cluster) and not requiring c..."},{"content":"<div class=\"display-flex-tablet justify-content-space-between-tablet page-metadata-container\"><ul class=\"metadata page-metadata\" data-bi-name=\"page info\" lang=\"en-us\" dir=\"ltr\" xml:lang=\"en-us\"><li>Article</li>\n<li><time class=\"is-invisible\" data-article-date=\"\" aria-label=\"Article review date\" datetime=\"2022-04-01T22:02:00Z\" data-article-date-source=\"git\">04/01/2022</time></li>\n</ul></div><p>Where possible, we recommend using Apache Cassandra native replication to migrate data from your existing cluster into Azure Managed Instance for Apache Cassandra by configuring a <a href=\"https://docs.microsoft.com/en-us/azure/managed-instance-apache-cassandra/configure-hybrid-cluster\" data-linktype=\"relative-path\">hybrid cluster</a>. This approach will use Apache Cassandra's gossip protocol to replicate data from your source data-center into your new managed instance datacenter. However, there may be some scenarios where your source database version isn't compatible, or a hybrid cluster setup is otherwise not feasible.</p><p>This tutorial describes how to migrate data to Migrate to Azure Managed Instance for Apache Cassandra in an offline fashion using the Cassandra Spark Connector, and Azure Databricks for Apache Spark.</p><h2 id=\"prerequisites\">Prerequisites</h2><ul><li>\n<p>Provision an Azure Managed Instance for Apache Cassandra cluster using <a href=\"https://docs.microsoft.com/en-us/azure/managed-instance-apache-cassandra/create-cluster-portal\" data-linktype=\"relative-path\">Azure portal</a> or <a href=\"https://docs.microsoft.com/en-us/azure/managed-instance-apache-cassandra/create-cluster-cli\" data-linktype=\"relative-path\">Azure CLI</a> and ensure you can <a href=\"https://docs.microsoft.com/en-us/azure/managed-instance-apache-cassandra/create-cluster-portal#connecting-to-your-cluster\" data-linktype=\"relative-path\">connect to your cluster with CQLSH</a>.</p>\n</li>\n<li>\n<p><a href=\"https://docs.microsoft.com/en-us/azure/managed-instance-apache-cassandra/deploy-cluster-databricks\" data-linktype=\"relative-path\">Provision an Azure Databricks account inside your Managed Cassandra VNet</a>. Ensure it also has network access to your source Cassandra cluster.</p>\n</li>\n<li>\n<p>Ensure you've already migrated the keyspace/table scheme from your source Cassandra database to your target Cassandra Managed Instance database.</p>\n</li>\n</ul><h2 id=\"provision-an-azure-databricks-cluster\">Provision an Azure Databricks cluster</h2><p>We recommend selecting Databricks runtime version 7.5, which supports Spark 3.0.</p><p><img src=\"https://docs.microsoft.com/en-us/azure/cosmos-db/cassandra/media/migrate-data-databricks/databricks-runtime.png\" alt=\"Screenshot that shows finding the Databricks runtime version.\" data-linktype=\"relative-path\" referrerpolicy=\"no-referrer\" /></p><h2 id=\"add-dependencies\">Add dependencies</h2><p>Add the Apache Spark Cassandra Connector library to your cluster to connect to both native and Azure Cosmos DB Cassandra endpoints. In your cluster, select <strong>Libraries</strong> &gt; <strong>Install New</strong> &gt; <strong>Maven</strong>, and then add <code>com.datastax.spark:spark-cassandra-connector-assembly_2.12:3.0.0</code> in Maven coordinates.</p><p><img src=\"https://docs.microsoft.com/en-us/azure/cosmos-db/cassandra/media/migrate-data-databricks/databricks-search-packages.png\" alt=\"Screenshot that shows searching for Maven packages in Databricks.\" data-linktype=\"relative-path\" referrerpolicy=\"no-referrer\" /></p><p>Select <strong>Install</strong>, and then restart the cluster when installation is complete.</p><div class=\"NOTE\"><p>Note</p><p>Make sure that you restart the Databricks cluster after the Cassandra Connector library has been installed.</p></div><h2 id=\"create-scala-notebook-for-migration\">Create Scala Notebook for migration</h2><p>Create a Scala Notebook in Databricks. Replace your source and target Cassandra configurations with the corresponding credentials, and source and target keyspaces and tables. Then run the following code:</p><pre class=\"lang-scala\">import com.datastax.spark.connector._\nimport com.datastax.spark.connector.cql._\nimport org.apache.spark.SparkContext\n// source cassandra configs\nval sourceCassandra = Map( \n    \"spark.cassandra.connection.host\" -&gt; \"&lt;Source Cassandra Host&gt;\",\n    \"spark.cassandra.connection.port\" -&gt; \"9042\",\n    \"spark.cassandra.auth.username\" -&gt; \"&lt;USERNAME&gt;\",\n    \"spark.cassandra.auth.password\" -&gt; \"&lt;PASSWORD&gt;\",\n    \"spark.cassandra.connection.ssl.enabled\" -&gt; \"false\",\n    \"keyspace\" -&gt; \"&lt;KEYSPACE&gt;\",\n    \"table\" -&gt; \"&lt;TABLE&gt;\"\n)\n//target cassandra configs\nval targetCassandra = Map( \n    \"spark.cassandra.connection.host\" -&gt; \"&lt;Source Cassandra Host&gt;\",\n    \"spark.cassandra.connection.port\" -&gt; \"9042\",\n    \"spark.cassandra.auth.username\" -&gt; \"&lt;USERNAME&gt;\",\n    \"spark.cassandra.auth.password\" -&gt; \"&lt;PASSWORD&gt;\",\n    \"spark.cassandra.connection.ssl.enabled\" -&gt; \"true\",\n    \"keyspace\" -&gt; \"&lt;KEYSPACE&gt;\",\n    \"table\" -&gt; \"&lt;TABLE&gt;\",\n    //throughput related settings below - tweak these depending on data volumes. \n    \"spark.cassandra.output.batch.size.rows\"-&gt; \"1\",\n    \"spark.cassandra.output.concurrent.writes\" -&gt; \"1000\",\n    \"spark.cassandra.connection.remoteConnectionsPerExecutor\" -&gt; \"10\",\n    \"spark.cassandra.concurrent.reads\" -&gt; \"512\",\n    \"spark.cassandra.output.batch.grouping.buffer.size\" -&gt; \"1000\",\n    \"spark.cassandra.connection.keep_alive_ms\" -&gt; \"600000000\"\n)\n//Read from source Cassandra\nval DFfromSourceCassandra = sqlContext\n  .read\n  .format(\"org.apache.spark.sql.cassandra\")\n  .options(sourceCassandra)\n  .load\n//Write to target Cassandra\nDFfromSourceCassandra\n  .write\n  .format(\"org.apache.spark.sql.cassandra\")\n  .options(targetCassandra)\n  .mode(SaveMode.Append) // only required for Spark 3.x\n  .save\n</pre><div class=\"NOTE\"><p>Note</p><p>If you have a need to preserve the original <code>writetime</code> of each row, refer to the <a href=\"https://github.com/Azure-Samples/cassandra-migrator\" data-linktype=\"external\">cassandra migrator</a> sample.</p></div><h2 id=\"next-steps\">Next steps</h2><div class=\"nextstepaction\"><p><a href=\"https://docs.microsoft.com/en-us/azure/managed-instance-apache-cassandra/manage-resources-cli\" data-linktype=\"relative-path\">Manage Azure Managed Instance for Apache Cassandra resources using Azure CLI</a></p></div>","id":"96345e36-1ce5-5da7-bac0-8e4ca8d24669","title":"Migrate to Azure Managed Instance for Apache Cassandra using Apache Spark","origin_url":"https://docs.microsoft.com/en-us/azure/managed-instance-apache-cassandra/spark-migration","url":"https://docs.microsoft.com/en-us/azure/managed-instance-apache-cassandra/spark-migration","wallabag_created_at":"2022-08-18T16:17:51+00:00","published_at":null,"published_by":"['TheovanKraay']","reading_time":2,"domain_name":"docs.microsoft.com","preview_picture":"https://learn.microsoft.com/en-us/media/open-graph-image.png","tags":["proxy","cassandra","spark","azure"],"description":"Article\n04/01/2022\nWhere possible, we recommend using Apache Cassandra native replication to migrate data from your existing cluster into Azure Managed Instance for Apache Cassandra by configuring a h..."},{"content":"<div class=\"display-flex-tablet justify-content-space-between-tablet page-metadata-container\"><ul class=\"metadata page-metadata\" data-bi-name=\"page info\" lang=\"en-us\" dir=\"ltr\" xml:lang=\"en-us\"><li>Article</li>\n<li><time class=\"is-invisible\" data-article-date=\"\" aria-label=\"Article review date\" datetime=\"2021-11-29T18:19:00Z\" data-article-date-source=\"git\">11/29/2021</time></li>\n</ul></div><p>Where possible, we recommend using the Apache Cassandra native capability to migrate data from your existing cluster into Azure Managed Instance for Apache Cassandra by configuring a <a href=\"https://docs.microsoft.com/en-us/azure/managed-instance-apache-cassandra/configure-hybrid-cluster\" data-linktype=\"relative-path\">hybrid cluster</a>. This capability uses Apache Cassandra's gossip protocol to replicate data from your source datacenter into your new managed-instance datacenter in a seamless way. However, there might be some scenarios where your source database version is not compatible, or a hybrid cluster setup is otherwise not feasible.</p><p>This tutorial describes how to migrate data to Azure Managed Instance for Apache Cassandra in a live fashion by using a <a href=\"https://github.com/Azure-Samples/cassandra-proxy\" data-linktype=\"external\">dual-write proxy</a> and Apache Spark. The dual-write proxy is used to capture live changes, while historical data is copied in bulk using Apache Spark. The benefits of this approach are:</p><ul><li><strong>Minimal application changes</strong>. The proxy can accept connections from your application code with few or no configuration changes. It will route all requests to your source database and asynchronously route writes to a secondary target.</li>\n<li><strong>Client wire protocol dependency</strong>. Because this approach is not dependent on back-end resources or internal protocols, it can be used with any source or target Cassandra system that implements the Apache Cassandra wire protocol.</li>\n</ul><p>The following image illustrates the approach.</p><p><img src=\"https://docs.microsoft.com/en-us/azure/managed-instance-apache-cassandra/media/migration/live-migration.gif\" alt=\"Animation that shows the live migration of data to Azure Managed Instance for Apache Cassandra.\" data-linktype=\"relative-path\" referrerpolicy=\"no-referrer\" /></p><h2 id=\"prerequisites\">Prerequisites</h2><ul><li>\n<p>Provision an Azure Managed Instance for Apache Cassandra cluster by using the <a href=\"https://docs.microsoft.com/en-us/azure/managed-instance-apache-cassandra/create-cluster-portal\" data-linktype=\"relative-path\">Azure portal</a> or the <a href=\"https://docs.microsoft.com/en-us/azure/managed-instance-apache-cassandra/create-cluster-cli\" data-linktype=\"relative-path\">Azure CLI</a>. Ensure that you can <a href=\"https://docs.microsoft.com/en-us/azure/managed-instance-apache-cassandra/create-cluster-portal#connecting-to-your-cluster\" data-linktype=\"relative-path\">connect to your cluster with CQLSH</a>.</p>\n</li>\n<li>\n<p><a href=\"https://docs.microsoft.com/en-us/azure/managed-instance-apache-cassandra/deploy-cluster-databricks\" data-linktype=\"relative-path\">Provision an Azure Databricks account inside your Managed Cassandra virtual network</a>. Ensure that the account has network access to your source Cassandra cluster. We'll create a Spark cluster in this account for the historical data load.</p>\n</li>\n<li>\n<p>Ensure that you've already migrated the keyspace/table scheme from your source Cassandra database to your target Cassandra managed-instance database.</p>\n</li>\n</ul><h2 id=\"provision-a-spark-cluster\">Provision a Spark cluster</h2><p>We recommend selecting Azure Databricks runtime version 7.5, which supports Spark 3.0.</p><p><img src=\"https://docs.microsoft.com/en-us/azure/cosmos-db/cassandra/media/migrate-data-databricks/databricks-runtime.png\" alt=\"Screenshot that shows finding the Azure Databricks runtime version.\" data-linktype=\"relative-path\" referrerpolicy=\"no-referrer\" /></p><h2 id=\"add-spark-dependencies\">Add Spark dependencies</h2><p>You need to add the Apache Spark Cassandra Connector library to your cluster to connect to any wire protocol compatible Apache Cassandra endpoints. In your cluster, select <strong>Libraries</strong> &gt; <strong>Install New</strong> &gt; <strong>Maven</strong>, and then add <code>com.datastax.spark:spark-cassandra-connector-assembly_2.12:3.0.0</code> in Maven coordinates.</p><div class=\"IMPORTANT\"><p>Important</p><p>If you have a requirement to preserve Apache Cassandra <code>writetime</code> for each row during the migration, we recommend using <a href=\"https://github.com/Azure-Samples/cassandra-migrator\" data-linktype=\"external\">this sample</a>. The dependency jar in this sample also contains the Spark connector, so you should install this instead of the connector assembly above. This sample is also useful if you want to perform a row comparison validation between source and target after historic data load is complete. See sections \"<a href=\"https://docs.microsoft.com/en-us/azure/managed-instance-apache-cassandra/dual-write-proxy-migration#run-the-historical-data-load\" data-linktype=\"relative-path\">run the historical data load</a>\" and \"<a href=\"https://docs.microsoft.com/en-us/azure/managed-instance-apache-cassandra/dual-write-proxy-migration#validate-the-source-and-target\" data-linktype=\"relative-path\">validate the source and target</a>\" below for more details.</p></div><p><img src=\"https://docs.microsoft.com/en-us/azure/cosmos-db/cassandra/media/migrate-data-databricks/databricks-search-packages.png\" alt=\"Screenshot that shows searching for Maven packages in Azure Databricks.\" data-linktype=\"relative-path\" referrerpolicy=\"no-referrer\" /></p><p>Select <strong>Install</strong>, and then restart the cluster when installation is complete.</p><div class=\"NOTE\"><p>Note</p><p>Be sure to restart the Azure Databricks cluster after the Cassandra Connector library is installed.</p></div><h2 id=\"install-the-dual-write-proxy\">Install the dual-write proxy</h2><p>For optimal performance during dual writes, we recommend installing the proxy on all nodes in your source Cassandra cluster.</p><pre class=\"lang-bash\">#assuming you do not have git already installed\nsudo apt-get install git \n#assuming you do not have maven already installed\nsudo apt install maven\n#clone repo for dual-write proxy\ngit clone https://github.com/Azure-Samples/cassandra-proxy.git\n#change directory\ncd cassandra-proxy\n#compile the proxy\nmvn package\n</pre><h2 id=\"start-the-dual-write-proxy\">Start the dual-write proxy</h2><p>We recommend that you install the proxy on all nodes in your source Cassandra cluster. At minimum, run the following command to start the proxy on each node. Replace <code>&lt;target-server&gt;</code> with an IP or server address from one of the nodes in the target cluster. Replace <code>&lt;path to JKS file&gt;</code> with path to a local .jks file, and replace <code>&lt;keystore password&gt;</code> with the corresponding password.</p><pre class=\"lang-bash\">java -jar target/cassandra-proxy-1.0-SNAPSHOT-fat.jar localhost &lt;target-server&gt; --proxy-jks-file &lt;path to JKS file&gt; --proxy-jks-password &lt;keystore password&gt;\n</pre><p>Starting the proxy in this way assumes that the following are true:</p><ul><li>Source and target endpoints have the same username and password.</li>\n<li>Source and target endpoints implement Secure Sockets Layer (SSL).</li>\n</ul><p>If your source and target endpoints can't meet these criteria, read on for further configuration options.</p><h3 id=\"configure-ssl\">Configure SSL</h3><p>For SSL, you can either implement an existing keystore (for example, the one that your source cluster uses) or create a self-signed certificate by using <code>keytool</code>:</p><pre class=\"lang-bash\">keytool -genkey -keyalg RSA -alias selfsigned -keystore keystore.jks -storepass password -validity 360 -keysize 2048\n</pre><p>You can also disable SSL for source or target endpoints if they don't implement SSL. Use the <code>--disable-source-tls</code> or <code>--disable-target-tls</code> flags:</p><pre class=\"lang-bash\">java -jar target/cassandra-proxy-1.0-SNAPSHOT-fat.jar localhost &lt;target-server&gt; --source-port 9042 --target-port 10350 --proxy-jks-file &lt;path to JKS file&gt; --proxy-jks-password &lt;keystore password&gt; --target-username &lt;username&gt; --target-password &lt;password&gt; --disable-source-tls true  --disable-target-tls true \n</pre><div class=\"NOTE\"><p>Note</p><p>Make sure your client application uses the same keystore and password as the ones used for the dual-write proxy when you're building SSL connections to the database via the proxy.</p></div><h3 id=\"configure-the-credentials-and-port\">Configure the credentials and port</h3><p>By default, the source credentials will be passed through from your client app. The proxy will use the credentials for making connections to the source and target clusters. As mentioned earlier, this process assumes that the source and target credentials are the same. If necessary, you can specify a different username and password for the target Cassandra endpoint separately when starting the proxy:</p><pre class=\"lang-bash\">java -jar target/cassandra-proxy-1.0-SNAPSHOT-fat.jar localhost &lt;target-server&gt; --proxy-jks-file &lt;path to JKS file&gt; --proxy-jks-password &lt;keystore password&gt; --target-username &lt;username&gt; --target-password &lt;password&gt;\n</pre><p>The default source and target ports, when not specified, will be 9042. If either the target or the source Cassandra endpoint runs on a different port, you can use <code>--source-port</code> or <code>--target-port</code> to specify a different port number:</p><pre class=\"lang-bash\">java -jar target/cassandra-proxy-1.0-SNAPSHOT-fat.jar localhost &lt;target-server&gt; --source-port 9042 --target-port 10350 --proxy-jks-file &lt;path to JKS file&gt; --proxy-jks-password &lt;keystore password&gt; --target-username &lt;username&gt; --target-password &lt;password&gt;\n</pre><h3 id=\"deploy-the-proxy-remotely\">Deploy the proxy remotely</h3><p>There might be circumstances in which you don't want to install the proxy on the cluster nodes themselves, and you prefer to install it on a separate machine. In that scenario, you need to specify the IP address of <code>&lt;source-server&gt;</code>:</p><pre class=\"lang-bash\">java -jar target/cassandra-proxy-1.0-SNAPSHOT-fat.jar &lt;source-server&gt; &lt;destination-server&gt;\n</pre><div class=\"WARNING\"><p>Warning</p><p>Installing and running the proxy remotely on a separate machine (rather than running it on all nodes in your source Apache Cassandra cluster) will impact performance while the live migration occurs. While it will work functionally, the client driver won't be able to open connections to all nodes within the cluster, and will rely on the single co-ordinator node (where the proxy is installed) to make connections.</p></div><h3 id=\"allow-zero-application-code-changes\">Allow zero application code changes</h3><p>By default, the proxy listens on port 29042. The application code must be changed to point to this port. However, you can change the port that the proxy listens on. You might do this if you want to eliminate application-level code changes by:</p><ul><li>Having the source Cassandra server run on a different port.</li>\n<li>Having the proxy run on the standard Cassandra port 9042.</li>\n</ul><pre class=\"lang-bash\">java -jar target/cassandra-proxy-1.0-SNAPSHOT-fat.jar source-server destination-server --proxy-port 9042\n</pre><div class=\"NOTE\"><p>Note</p><p>Installing the proxy on cluster nodes does not require restart of the nodes. However, if you have many application clients and prefer to have the proxy running on the standard Cassandra port 9042 in order to eliminate any application-level code changes, you need to change the <a href=\"https://cassandra.apache.org/doc/latest/cassandra/faq/#what-ports-does-cassandra-use\" data-linktype=\"external\">Apache Cassandra default port</a>. You then need to restart the nodes in your cluster, and configure the source port to be the new port that you defined for your source Cassandra cluster.</p><p>In the following example, we change the source Cassandra cluster to run on port 3074, and we start the cluster on port 9042:</p><pre class=\"lang-bash\">java -jar target/cassandra-proxy-1.0-SNAPSHOT-fat.jar source-server destination-server --proxy-port 9042 --source-port 3074\n</pre></div><h3 id=\"force-protocols\">Force protocols</h3><p>The proxy has functionality to force protocols, which might be necessary if the source endpoint is more advanced than the target or is otherwise unsupported. In that case, you can specify <code>--protocol-version</code> and <code>--cql-version</code> to force the protocol to comply with the target:</p><pre class=\"lang-bash\">java -jar target/cassandra-proxy-1.0-SNAPSHOT-fat.jar source-server destination-server --protocol-version 4 --cql-version 3.11\n</pre><p>After the dual-write proxy is running, you'll need to change the port on your application client and restart. (Or change the Cassandra port and restart the cluster if you've chosen that approach.) The proxy will then start forwarding writes to the target endpoint. You can learn about <a href=\"https://github.com/Azure-Samples/cassandra-proxy#monitoring\" data-linktype=\"external\">monitoring and metrics</a> available in the proxy tool.</p><h2 id=\"run-the-historical-data-load\">Run the historical data load</h2><p>To load the data, create a Scala notebook in your Azure Databricks account. Replace your source and target Cassandra configurations with the corresponding credentials, and replace the source and target keyspaces and tables. Add more variables for each table as required to the following sample, and then run. After your application starts sending requests to the dual-write proxy, you're ready to migrate historical data.</p><pre class=\"lang-scala\">import com.datastax.spark.connector._\nimport com.datastax.spark.connector.cql._\nimport org.apache.spark.SparkContext\n// source cassandra configs\nval sourceCassandra = Map( \n    \"spark.cassandra.connection.host\" -&gt; \"&lt;Source Cassandra Host&gt;\",\n    \"spark.cassandra.connection.port\" -&gt; \"9042\",\n    \"spark.cassandra.auth.username\" -&gt; \"&lt;USERNAME&gt;\",\n    \"spark.cassandra.auth.password\" -&gt; \"&lt;PASSWORD&gt;\",\n    \"spark.cassandra.connection.ssl.enabled\" -&gt; \"true\",\n    \"keyspace\" -&gt; \"&lt;KEYSPACE&gt;\",\n    \"table\" -&gt; \"&lt;TABLE&gt;\"\n)\n//target cassandra configs\nval targetCassandra = Map( \n    \"spark.cassandra.connection.host\" -&gt; \"&lt;Source Cassandra Host&gt;\",\n    \"spark.cassandra.connection.port\" -&gt; \"9042\",\n    \"spark.cassandra.auth.username\" -&gt; \"&lt;USERNAME&gt;\",\n    \"spark.cassandra.auth.password\" -&gt; \"&lt;PASSWORD&gt;\",\n    \"spark.cassandra.connection.ssl.enabled\" -&gt; \"true\",\n    \"keyspace\" -&gt; \"&lt;KEYSPACE&gt;\",\n    \"table\" -&gt; \"&lt;TABLE&gt;\",\n    //throughput related settings below - tweak these depending on data volumes. \n    \"spark.cassandra.output.batch.size.rows\"-&gt; \"1\",\n    \"spark.cassandra.output.concurrent.writes\" -&gt; \"1000\",\n    \"spark.cassandra.connection.remoteConnectionsPerExecutor\" -&gt; \"1\",\n    \"spark.cassandra.concurrent.reads\" -&gt; \"512\",\n    \"spark.cassandra.output.batch.grouping.buffer.size\" -&gt; \"1000\",\n    \"spark.cassandra.connection.keep_alive_ms\" -&gt; \"600000000\"\n)\n//set timestamp to ensure it is before read job starts\nval timestamp: Long = System.currentTimeMillis / 1000\n//Read from source Cassandra\nval DFfromSourceCassandra = sqlContext\n  .read\n  .format(\"org.apache.spark.sql.cassandra\")\n  .options(sourceCassandra)\n  .load\n//Write to target Cassandra\nDFfromSourceCassandra\n  .write\n  .format(\"org.apache.spark.sql.cassandra\")\n  .options(targetCassandra)\n  .option(\"writetime\", timestamp)\n  .mode(SaveMode.Append)\n  .save\n</pre><div class=\"NOTE\"><p>Note</p><p>In the preceding Scala sample, you'll notice that <code>timestamp</code> is being set to the current time before reading all the data in the source table. Then, <code>writetime</code> is being set to this backdated time stamp. This ensures that records that are written from the historical data load to the target endpoint can't overwrite updates that come in with a later time stamp from the dual-write proxy while historical data is being read.</p></div><div class=\"IMPORTANT\"><p>Important</p><p>If you need to preserve <em>exact</em> time stamps for any reason, you should take a historical data migration approach that preserves time stamps, such as <a href=\"https://github.com/Azure-Samples/cassandra-migrator\" data-linktype=\"external\">this sample</a>. The dependency jar in the sample also contains the Spark connector, so you do not need to install the Spark connector assembly mentioned in the earlier pre-requisites - having both installed in your Spark cluster will cause conflicts.</p></div><p>After the historical data load is complete, your databases should be in sync and ready for cutover. However, we recommend that you validate the source and target to ensure they match before finally cutting over.</p><div class=\"NOTE\"><p>Note</p><p>If you used the <a href=\"https://github.com/Azure-Samples/cassandra-migrator\" data-linktype=\"external\">cassandra migrator</a> sample mentioned above for preserving <code>writetime</code>, this includes the capability to <a href=\"https://github.com/Azure-Samples/cassandra-migrator#validate-migration\" data-linktype=\"external\">validate the migration</a> by <a href=\"https://github.com/Azure-Samples/cassandra-migrator/blob/main/build_files/src/main/scala/com/cassandra/migrator/validation/RowComparisonFailure.scala\" data-linktype=\"external\">comparing rows</a> in source and target based on certain tolerances.</p></div><h2 id=\"next-steps\">Next steps</h2><div class=\"nextstepaction\"><p><a href=\"https://docs.microsoft.com/en-us/azure/managed-instance-apache-cassandra/manage-resources-cli\" data-linktype=\"relative-path\">Manage Azure Managed Instance for Apache Cassandra resources using Azure CLI</a></p></div>","id":"cc83865b-46de-5403-85e5-07e1672af9b1","title":"Live migration to Azure Managed Instance for Apache Cassandra using Apache Spark and a dual-write proxy","origin_url":"https://docs.microsoft.com/en-us/azure/managed-instance-apache-cassandra/dual-write-proxy-migration","url":"https://docs.microsoft.com/en-us/azure/managed-instance-apache-cassandra/dual-write-proxy-migration","wallabag_created_at":"2022-08-18T16:16:36+00:00","published_at":null,"published_by":"['TheovanKraay']","reading_time":10,"domain_name":"docs.microsoft.com","preview_picture":"https://learn.microsoft.com/en-us/media/open-graph-image.png","tags":["proxy","managed.services","cassandra","azure","cql"],"description":"Article\n11/29/2021\nWhere possible, we recommend using the Apache Cassandra native capability to migrate data from your existing cluster into Azure Managed Instance for Apache Cassandra by configuring ..."},{"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=\"c14\" referrerpolicy=\"no-referrer\" /></a> <a href=\"https://goreportcard.com/report/github.com/datastax/cql-proxy\" rel=\"nofollow\"><img src=\"https://camo.githubusercontent.com/5748bb775a779e13f2b73f1c2263b54cb1885ad97d6fa59b4c4956b480373a76/68747470733a2f2f676f7265706f7274636172642e636f6d2f62616467652f6769746875622e636f6d2f64617461737461782f63716c2d70726f7879\" alt=\"Go Report Card\" data-canonical-src=\"https://goreportcard.com/badge/github.com/datastax/cql-proxy\" class=\"c14\" referrerpolicy=\"no-referrer\" /></a></p><h2 dir=\"auto\"><a id=\"user-content-table-of-contents\" class=\"anchor\" aria-hidden=\"true\" href=\"https://github.com/datastax/cql-proxy/blob/main/README.md#table-of-contents\"></a>Table of Contents</h2><h2 dir=\"auto\"><a id=\"user-content-what-is-cql-proxy\" class=\"anchor\" aria-hidden=\"true\" href=\"https://github.com/datastax/cql-proxy/blob/main/README.md#what-is-cql-proxy\"></a>What is <code>cql-proxy</code>?</h2><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=\"c14\" 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><h2 dir=\"auto\"><a id=\"user-content-when-to-use-cql-proxy\" class=\"anchor\" aria-hidden=\"true\" href=\"https://github.com/datastax/cql-proxy/blob/main/README.md#when-to-use-cql-proxy\"></a>When to use <code>cql-proxy</code></h2><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><h2 dir=\"auto\"><a id=\"user-content-configuration\" class=\"anchor\" aria-hidden=\"true\" href=\"https://github.com/datastax/cql-proxy/blob/main/README.md#configuration\"></a>Configuration</h2><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\" 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) -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  -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><h3 dir=\"auto\"><a id=\"user-content-using-flags\" class=\"anchor\" aria-hidden=\"true\" href=\"https://github.com/datastax/cql-proxy/blob/main/README.md#using-flags\"></a>Using flags</h3><div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" data-snippet-clipboard-copy-content=\"docker run -p 9042:9042 --rm datastax/cql-proxy:v0.1.3 --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.3 \\\n  --astra-token &lt;astra-token&gt; --astra-database-id &lt;astra-datbase-id&gt;</pre></div><h3 dir=\"auto\"><a id=\"user-content-using-environment-variables\" class=\"anchor\" aria-hidden=\"true\" href=\"https://github.com/datastax/cql-proxy/blob/main/README.md#using-environment-variables\"></a>Using environment variables</h3><div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" data-snippet-clipboard-copy-content=\"docker run -p 9042:9042 --rm datastax/cql-proxy:v0.1.3 -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.3 \\\n  -e ASTRA_TOKEN=&lt;astra-token&gt; -e ASTRA_DATABASE_ID=&lt;astra-datbase-id&gt;</pre></div><h3 dir=\"auto\"><a id=\"user-content-using-a-configuration-file\" class=\"anchor\" aria-hidden=\"true\" href=\"https://github.com/datastax/cql-proxy/blob/main/README.md#using-a-configuration-file\"></a>Using a configuration file</h3><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\" 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\" 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><h4 dir=\"auto\"><a id=\"user-content-setting-up-peer-proxies\" class=\"anchor\" aria-hidden=\"true\" href=\"https://github.com/datastax/cql-proxy/blob/main/README.md#setting-up-peer-proxies\"></a>Setting up peer proxies</h4><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><h5 dir=\"auto\"><a id=\"user-content-multi-region-setup\" class=\"anchor\" aria-hidden=\"true\" href=\"https://github.com/datastax/cql-proxy/blob/main/README.md#multi-region-setup\"></a>Multi-region setup</h5><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\" 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\" 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\" 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><h2 dir=\"auto\"><a id=\"user-content-getting-started\" class=\"anchor\" aria-hidden=\"true\" href=\"https://github.com/datastax/cql-proxy/blob/main/README.md#getting-started\"></a>Getting started</h2><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><h3 dir=\"auto\"><a id=\"user-content-locally-build-and-run\" class=\"anchor\" aria-hidden=\"true\" href=\"https://github.com/datastax/cql-proxy/blob/main/README.md#locally-build-and-run\"></a>Locally build and run</h3><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\" 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\" 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\" 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><h3 dir=\"auto\"><a id=\"user-content-run-a-cql-proxy-docker-image\" class=\"anchor\" aria-hidden=\"true\" href=\"https://github.com/datastax/cql-proxy/blob/main/README.md#run-a-cql-proxy-docker-image\"></a>Run a <code>cql-proxy</code> docker image</h3><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\" data-snippet-clipboard-copy-content=\"docker run -p 9042:9042 datastax/cql-proxy:v0.1.3 --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.3 \\\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\" 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.3 --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.3 \\\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\" data-snippet-clipboard-copy-content=\"docker run -p 9042:9042 datastax/cql-proxy:v0.1.3 --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.3 \\\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.3</code>.</p><h3 dir=\"auto\"><a id=\"user-content-use-kubernetes\" class=\"anchor\" aria-hidden=\"true\" href=\"https://github.com/datastax/cql-proxy/blob/main/README.md#use-kubernetes\"></a>Use Kubernetes</h3><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\" 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\" 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\" 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\" data-snippet-clipboard-copy-content=\"kubectl logs &lt;deployment-name&gt;\"><pre>kubectl logs &lt;deployment-name&gt;</pre></div>\n</li>\n</ol><h2 dir=\"auto\"><a id=\"user-content-known-issues\" class=\"anchor\" aria-hidden=\"true\" href=\"https://github.com/datastax/cql-proxy/blob/main/README.md#known-issues\"></a>Known issues</h2><h3 dir=\"auto\"><a id=\"user-content-token-aware-load-balancing\" class=\"anchor\" aria-hidden=\"true\" href=\"https://github.com/datastax/cql-proxy/blob/main/README.md#token-aware-load-balancing\"></a>Token-aware load balancing</h3><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":"f9307803-a14a-5395-be5c-7025a773a5fb","title":"cql-proxy/README.md at main · datastax/cql-proxy","origin_url":"https://github.com/datastax/cql-proxy/blob/main/README.md","url":"https://github.com/datastax/cql-proxy/blob/main/README.md","wallabag_created_at":"2022-07-13T21:05:55+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":["proxy","datastax","cassandra","cql"],"description":" Table of ContentsWhat is cql-proxy?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..."},{"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/Azure-Samples/cassandra-proxy\">cassandra-proxy</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=%2FAzure-Samples%2Fcassandra-proxy\" 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/Azure-Samples/cassandra-proxy&quot;,&quot;user_id&quot;:null}}\" data-hydro-click-hmac=\"b5a254faa5f75a293f42616145a4ca0346670b5e2c81abc2dc874b92bce832fb\" 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=%2FAzure-Samples%2Fcassandra-proxy\" 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;:360271267,&quot;auth_type&quot;:&quot;LOG_IN&quot;,&quot;originating_url&quot;:&quot;https://github.com/Azure-Samples/cassandra-proxy&quot;,&quot;user_id&quot;:null}}\" data-hydro-click-hmac=\"d0389adef51529bfbe9680a35e688b57bd0a23ad1cc2d6bec12d4580118f1eca\" aria-label=\"You must be signed in to fork a repository\" data-view-component=\"true\" class=\"tooltipped tooltipped-s btn-sm btn\">Fork 8</a></li>\n<li>\n<p><a href=\"https://github.com/login?return_to=%2FAzure-Samples%2Fcassandra-proxy\" 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;:360271267,&quot;auth_type&quot;:&quot;LOG_IN&quot;,&quot;originating_url&quot;:&quot;https://github.com/Azure-Samples/cassandra-proxy&quot;,&quot;user_id&quot;:null}}\" data-hydro-click-hmac=\"7ee24902e203f553bff5e79ee83d6aa1710a663f5978ba1ad37bd828fb5df5eb\" 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 11</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\">A dual write proxy for Apache Cassandra</p><h3 class=\"sr-only\">License</h3><p><a href=\"https://github.com/Azure-Samples/cassandra-proxy/blob/main/LICENSE.md\" 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/Azure-Samples/cassandra-proxy/stargazers\"> 11 stars</a> <a class=\"Link--secondary no-underline\" href=\"https://github.com/Azure-Samples/cassandra-proxy/network/members\"> 8 forks</a></p><div class=\"d-flex\"><p><a href=\"https://github.com/login?return_to=%2FAzure-Samples%2Fcassandra-proxy\" 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;:360271267,&quot;auth_type&quot;:&quot;LOG_IN&quot;,&quot;originating_url&quot;:&quot;https://github.com/Azure-Samples/cassandra-proxy&quot;,&quot;user_id&quot;:null}}\" data-hydro-click-hmac=\"7ee24902e203f553bff5e79ee83d6aa1710a663f5978ba1ad37bd828fb5df5eb\" 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=%2FAzure-Samples%2Fcassandra-proxy\" 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/Azure-Samples/cassandra-proxy&quot;,&quot;user_id&quot;:null}}\" data-hydro-click-hmac=\"b5a254faa5f75a293f42616145a4ca0346670b5e2c81abc2dc874b92bce832fb\" 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":"9eb68c23-743f-5366-9a75-2acb856b1a3f","title":"GitHub - Azure-Samples/cassandra-proxy: A dual write proxy for Apache Cassandra","origin_url":"https://github.com/Azure-Samples/cassandra-proxy","url":"https://github.com/Azure-Samples/cassandra-proxy","wallabag_created_at":"2022-06-08T20:35:28+00:00","published_at":null,"published_by":"['Azure-Samples']","reading_time":null,"domain_name":"github.com","preview_picture":"https://opengraph.githubassets.com/214e45c665bb2a7c7489426e39be89b9e891dc7ddb34f43ecd65485a696c07c5/Azure-Samples/cassandra-proxy","tags":["cassandra","proxy"],"description":"{{ message }}\n / cassandra-proxy PublicNotifications\nFork 8\n\n Star 11 \n\nA dual write proxy for Apache CassandraLicense Apache-2.0 license 11 stars  8 forks Star Notifications\n\n © 2022 GitHub, Inc.\n\n Y..."},{"content":"<div data-pjax-replace=\"\" id=\"js-flash-container\"><div class=\"flash flash-full  {{ className }}\"><div class=\"px-2\"><p>{{ message }}</p></div></div>\n  </div><div class=\"application-main\" data-commit-hovercards-enabled=\"\" data-discussion-hovercards-enabled=\"\" data-issue-and-pr-hovercards-enabled=\"\"><div itemscope=\"itemscope\" itemtype=\"http://schema.org/SoftwareSourceCode\" class=\"\"><main id=\"js-repo-pjax-container\" data-pjax-container=\"\"><div id=\"repository-container-header\" class=\"pt-3 hide-full-screen mb-5\" data-pjax-replace=\"\"><div class=\"d-flex mb-3 px-3 px-md-4 px-lg-5\"><ul class=\"pagehead-actions flex-shrink-0 d-none d-md-inline\"><li>\n      <a href=\"https://github.com/login?return_to=%2Fdatastaxdevs%2Fawesome-astra\" 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/datastaxdevs/awesome-astra/wiki/CQL-Proxy&quot;,&quot;user_id&quot;:null}}\" data-hydro-click-hmac=\"44d910fc2c08783cdd5774e9e4685adec85b47d76b507737b996ff2ac0520b83\" aria-label=\"You must be signed in to change notification settings\" data-view-component=\"true\" class=\"tooltipped tooltipped-s btn-sm btn\">  Notifications\n</a>\n  </li>\n  <li>\n        <a href=\"https://github.com/login?return_to=%2Fdatastaxdevs%2Fawesome-astra\" 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;:450291005,&quot;auth_type&quot;:&quot;LOG_IN&quot;,&quot;originating_url&quot;:&quot;https://github.com/datastaxdevs/awesome-astra/wiki/CQL-Proxy&quot;,&quot;user_id&quot;:null}}\" data-hydro-click-hmac=\"438f352e39a4cf60437011b187a2bc565fe31a5c6e74ccca63d0e68cf008f7eb\" aria-label=\"You must be signed in to fork a repository\" data-view-component=\"true\" class=\"tooltipped tooltipped-s btn-sm btn\">  Fork\n    2\n</a>\n  </li>\n  <li>\n        <div data-view-component=\"true\" class=\"BtnGroup d-flex\"><a href=\"https://github.com/login?return_to=%2Fdatastaxdevs%2Fawesome-astra\" 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;:450291005,&quot;auth_type&quot;:&quot;LOG_IN&quot;,&quot;originating_url&quot;:&quot;https://github.com/datastaxdevs/awesome-astra/wiki/CQL-Proxy&quot;,&quot;user_id&quot;:null}}\" data-hydro-click-hmac=\"03a8c8d30a8816cd75d565016eb19856d817c43428ab317fe8366065cd730743\" aria-label=\"You must be signed in to star a repository\" data-view-component=\"true\" class=\"tooltipped tooltipped-s btn-sm btn BtnGroup-item\">  \n          Star\n          2\n</a></div>\n  </li>\n  <li>\n    \n  </li>\n</ul></div></div>\n    </main></div></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\">\n                \n        © 2022 GitHub, Inc.\n        \n      </li>\n    </ul></div>\n  \n</footer><div id=\"ajax-error-message\" class=\"ajax-error-message flash flash-error\" hidden=\"hidden\">You can’t perform that action at this time.</div>\n  \n    <details class=\"details-reset details-overlay details-overlay-dark lh-default color-fg-default hx_rsm\" open=\"open\"><summary role=\"button\" aria-label=\"Close dialog\">\n      \n    </summary></details>","id":"997b956d-1233-59ff-9a8a-9f6bf36b53f1","title":"CQL Proxy · datastaxdevs/awesome-astra Wiki","origin_url":"https://github.com/datastaxdevs/awesome-astra/wiki/CQL-Proxy","url":"https://github.com/datastaxdevs/awesome-astra/wiki/CQL-Proxy","wallabag_created_at":"2022-02-17T22:02:08+00:00","published_at":null,"published_by":"['datastaxdevs']","reading_time":null,"domain_name":"github.com","preview_picture":"https://opengraph.githubassets.com/32e78986b1811ed5058d6111a251c4d10ef3e9fa3a3f0c7e605247236f485c57/datastax-archive/awesome-astra","tags":["proxy","astra","cassandra","cql"],"description":"{{ message }}\n\n  Notifications\n\n\n\n  Fork\n    2\n\n\n\n  \n          Star\n          2\n\n\n\n\n\n\n\n                \n        © 2022 GitHub, Inc.\n        \n      \n\nYou can’t perform that action at this time.\n\n"}],"skip":0,"limit":8,"totalCount":9,"currentPage":1,"url":"/tags/proxy"}},"staticQueryHashes":[]}