diff --git a/.gitignore b/.gitignore index 9cb86147e9..4f33eda38b 100644 --- a/.gitignore +++ b/.gitignore @@ -72,3 +72,6 @@ lib/jsr223/jython/cachedir lib/jsr223/scala/*.jar /.ant-targets-build.xml + +# Generated files from the documentation +doc/source/cassandra_config_file.rst diff --git a/doc/Makefile b/doc/Makefile index 778448a498..14e4c7ab01 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -14,7 +14,7 @@ ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) sou # the i18n builder cannot share the environment and doctrees with the others I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source -MAKE_CASSANDRA_YAML = python convert_yaml_to_rst.py ../conf/cassandra.yaml source/cassandra_config_file.rst +MAKE_CASSANDRA_YAML = python convert_yaml_to_rst.py ../conf/cassandra.yaml source/configuration/cassandra_config_file.rst .PHONY: help help: diff --git a/doc/convert_yaml_to_rst.py b/doc/convert_yaml_to_rst.py index 426286a1fd..398295d509 100644 --- a/doc/convert_yaml_to_rst.py +++ b/doc/convert_yaml_to_rst.py @@ -58,7 +58,7 @@ def convert(yaml_file, dest_file): lines = f.readlines()[7:] with open(dest_file, 'w') as outfile: - outfile.write("Cassandra Config File\n") + outfile.write("Cassandra Configuration File\n") outfile.write("=====================\n") # since comments preceed an option, this holds all of the comment diff --git a/doc/source/_static/extra.css b/doc/source/_static/extra.css index 1b65a86063..b55515ea3f 100644 --- a/doc/source/_static/extra.css +++ b/doc/source/_static/extra.css @@ -33,3 +33,11 @@ a.reference.internal:visited code.literal { max-width: 100%; overflow: visible; } + +table.contentstable { + margin: 0; +} + +td.rightcolumn { + padding-left: 30px; +} diff --git a/doc/source/_templates/indexcontent.html b/doc/source/_templates/indexcontent.html new file mode 100644 index 0000000000..a71a7e9f5d --- /dev/null +++ b/doc/source/_templates/indexcontent.html @@ -0,0 +1,33 @@ +{% extends "defindex.html" %} +{% block tables %} +

{% trans %}Main documentation parts:{% endtrans %}

+ + +
+ + + + + + + + + + +
+ +

{% trans %}Meta informations:{% endtrans %}

+ + + + +{% endblock %} diff --git a/doc/source/architecture.rst b/doc/source/architecture/dynamo.rst similarity index 72% rename from doc/source/architecture.rst rename to doc/source/architecture/dynamo.rst index 920941440f..d146471eb2 100644 --- a/doc/source/architecture.rst +++ b/doc/source/architecture/dynamo.rst @@ -14,14 +14,6 @@ .. See the License for the specific language governing permissions and .. limitations under the License. -Architecture -============ - -Overview --------- - -.. todo:: todo - Dynamo ------ @@ -143,75 +135,3 @@ still useful guarantee: reads are guaranteed to see the latest write from within If this type of strong consistency isn't required, lower consistency levels like ``ONE`` may be used to improve throughput, latency, and availability. - -Storage Engine --------------- - -.. _commit-log: - -CommitLog -^^^^^^^^^ - -.. todo:: todo - -.. _memtables: - -Memtables -^^^^^^^^^ - -Memtables are in-memory structures where Cassandra buffers writes. In general, there is one active memtable per table. -Eventually, memtables are flushed onto disk and become immutable `SSTables`_. This can be triggered in several -ways: - -- The memory usage of the memtables exceeds the configured threshold (see ``memtable_cleanup_threshold``) -- The :ref:`commit-log` approaches its maximum size, and forces memtable flushes in order to allow commitlog segments to - be freed - -Memtables may be stored entirely on-heap or partially off-heap, depending on ``memtable_allocation_type``. - -SSTables -^^^^^^^^ - -SSTables are the immutable data files that Cassandra uses for persisting data on disk. - -As SSTables are flushed to disk from :ref:`memtables` or are streamed from other nodes, Cassandra triggers compactions -which combine multiple SSTables into one. Once the new SSTable has been written, the old SSTables can be removed. - -Each SSTable is comprised of multiple components stored in separate files: - -``Data.db`` - The actual data, i.e. the contents of rows. - -``Index.db`` - An index from partition keys to positions in the ``Data.db`` file. For wide partitions, this may also include an - index to rows within a partition. - -``Summary.db`` - A sampling of (by default) every 128th entry in the ``Index.db`` file. - -``Filter.db`` - A Bloom Filter of the partition keys in the SSTable. - -``CompressionInfo.db`` - Metadata about the offsets and lengths of compression chunks in the ``Data.db`` file. - -``Statistics.db`` - Stores metadata about the SSTable, including information about timestamps, tombstones, clustering keys, compaction, - repair, compression, TTLs, and more. - -``Digest.crc32`` - A CRC-32 digest of the ``Data.db`` file. - -``TOC.txt`` - A plain text list of the component files for the SSTable. - -Within the ``Data.db`` file, rows are organized by partition. These partitions are sorted in token order (i.e. by a -hash of the partition key when the default partitioner, ``Murmur3Partition``, is used). Within a partition, rows are -stored in the order of their clustering keys. - -SSTables can be optionally compressed using block-based compression. - -Guarantees ----------- - -.. todo:: todo diff --git a/doc/source/architecture/guarantees.rst b/doc/source/architecture/guarantees.rst new file mode 100644 index 0000000000..c0b58d880f --- /dev/null +++ b/doc/source/architecture/guarantees.rst @@ -0,0 +1,20 @@ +.. Licensed to the Apache Software Foundation (ASF) under one +.. or more contributor license agreements. See the NOTICE file +.. distributed with this work for additional information +.. regarding copyright ownership. The ASF licenses this file +.. to you under the Apache License, Version 2.0 (the +.. "License"); you may not use this file except in compliance +.. with the License. You may obtain a copy of the License at +.. +.. http://www.apache.org/licenses/LICENSE-2.0 +.. +.. Unless required by applicable law or agreed to in writing, software +.. distributed under the License is distributed on an "AS IS" BASIS, +.. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +.. See the License for the specific language governing permissions and +.. limitations under the License. + +Guarantees +---------- + +.. todo:: todo diff --git a/doc/source/architecture/index.rst b/doc/source/architecture/index.rst new file mode 100644 index 0000000000..58eda13779 --- /dev/null +++ b/doc/source/architecture/index.rst @@ -0,0 +1,29 @@ +.. Licensed to the Apache Software Foundation (ASF) under one +.. or more contributor license agreements. See the NOTICE file +.. distributed with this work for additional information +.. regarding copyright ownership. The ASF licenses this file +.. to you under the Apache License, Version 2.0 (the +.. "License"); you may not use this file except in compliance +.. with the License. You may obtain a copy of the License at +.. +.. http://www.apache.org/licenses/LICENSE-2.0 +.. +.. Unless required by applicable law or agreed to in writing, software +.. distributed under the License is distributed on an "AS IS" BASIS, +.. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +.. See the License for the specific language governing permissions and +.. limitations under the License. + +Architecture +============ + +This section describes the general architecture of Apache Cassandra. + +.. toctree:: + :maxdepth: 2 + + overview + dynamo + storage_engine + guarantees + diff --git a/doc/source/architecture/overview.rst b/doc/source/architecture/overview.rst new file mode 100644 index 0000000000..005b15b94c --- /dev/null +++ b/doc/source/architecture/overview.rst @@ -0,0 +1,20 @@ +.. Licensed to the Apache Software Foundation (ASF) under one +.. or more contributor license agreements. See the NOTICE file +.. distributed with this work for additional information +.. regarding copyright ownership. The ASF licenses this file +.. to you under the Apache License, Version 2.0 (the +.. "License"); you may not use this file except in compliance +.. with the License. You may obtain a copy of the License at +.. +.. http://www.apache.org/licenses/LICENSE-2.0 +.. +.. Unless required by applicable law or agreed to in writing, software +.. distributed under the License is distributed on an "AS IS" BASIS, +.. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +.. See the License for the specific language governing permissions and +.. limitations under the License. + +Overview +-------- + +.. todo:: todo diff --git a/doc/source/architecture/storage_engine.rst b/doc/source/architecture/storage_engine.rst new file mode 100644 index 0000000000..e4114e5afb --- /dev/null +++ b/doc/source/architecture/storage_engine.rst @@ -0,0 +1,82 @@ +.. Licensed to the Apache Software Foundation (ASF) under one +.. or more contributor license agreements. See the NOTICE file +.. distributed with this work for additional information +.. regarding copyright ownership. The ASF licenses this file +.. to you under the Apache License, Version 2.0 (the +.. "License"); you may not use this file except in compliance +.. with the License. You may obtain a copy of the License at +.. +.. http://www.apache.org/licenses/LICENSE-2.0 +.. +.. Unless required by applicable law or agreed to in writing, software +.. distributed under the License is distributed on an "AS IS" BASIS, +.. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +.. See the License for the specific language governing permissions and +.. limitations under the License. + +Storage Engine +-------------- + +.. _commit-log: + +CommitLog +^^^^^^^^^ + +.. todo:: todo + +.. _memtables: + +Memtables +^^^^^^^^^ + +Memtables are in-memory structures where Cassandra buffers writes. In general, there is one active memtable per table. +Eventually, memtables are flushed onto disk and become immutable `SSTables`_. This can be triggered in several +ways: + +- The memory usage of the memtables exceeds the configured threshold (see ``memtable_cleanup_threshold``) +- The :ref:`commit-log` approaches its maximum size, and forces memtable flushes in order to allow commitlog segments to + be freed + +Memtables may be stored entirely on-heap or partially off-heap, depending on ``memtable_allocation_type``. + +SSTables +^^^^^^^^ + +SSTables are the immutable data files that Cassandra uses for persisting data on disk. + +As SSTables are flushed to disk from :ref:`memtables` or are streamed from other nodes, Cassandra triggers compactions +which combine multiple SSTables into one. Once the new SSTable has been written, the old SSTables can be removed. + +Each SSTable is comprised of multiple components stored in separate files: + +``Data.db`` + The actual data, i.e. the contents of rows. + +``Index.db`` + An index from partition keys to positions in the ``Data.db`` file. For wide partitions, this may also include an + index to rows within a partition. + +``Summary.db`` + A sampling of (by default) every 128th entry in the ``Index.db`` file. + +``Filter.db`` + A Bloom Filter of the partition keys in the SSTable. + +``CompressionInfo.db`` + Metadata about the offsets and lengths of compression chunks in the ``Data.db`` file. + +``Statistics.db`` + Stores metadata about the SSTable, including information about timestamps, tombstones, clustering keys, compaction, + repair, compression, TTLs, and more. + +``Digest.crc32`` + A CRC-32 digest of the ``Data.db`` file. + +``TOC.txt`` + A plain text list of the component files for the SSTable. + +Within the ``Data.db`` file, rows are organized by partition. These partitions are sorted in token order (i.e. by a +hash of the partition key when the default partitioner, ``Murmur3Partition``, is used). Within a partition, rows are +stored in the order of their clustering keys. + +SSTables can be optionally compressed using block-based compression. diff --git a/doc/source/bugs.rst b/doc/source/bugs.rst new file mode 100644 index 0000000000..ef10aabf8b --- /dev/null +++ b/doc/source/bugs.rst @@ -0,0 +1,20 @@ +.. Licensed to the Apache Software Foundation (ASF) under one +.. or more contributor license agreements. See the NOTICE file +.. distributed with this work for additional information +.. regarding copyright ownership. The ASF licenses this file +.. to you under the Apache License, Version 2.0 (the +.. "License"); you may not use this file except in compliance +.. with the License. You may obtain a copy of the License at +.. +.. http://www.apache.org/licenses/LICENSE-2.0 +.. +.. Unless required by applicable law or agreed to in writing, software +.. distributed under the License is distributed on an "AS IS" BASIS, +.. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +.. See the License for the specific language governing permissions and +.. limitations under the License. + +Reporting bugs +-------------- + +.. todo:: TODO diff --git a/doc/source/conf.py b/doc/source/conf.py index 85c494d5fd..9caf188b76 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -192,7 +192,9 @@ html_static_path = ['_static'] # Additional templates that should be rendered to pages, maps page names to # template names. # -# html_additional_pages = {} +html_additional_pages = { + 'index': 'indexcontent.html' +} # If false, no module index is generated. # diff --git a/doc/source/configuration/cassandra_config_file.rst b/doc/source/configuration/cassandra_config_file.rst new file mode 100644 index 0000000000..b7d1bbc7fe --- /dev/null +++ b/doc/source/configuration/cassandra_config_file.rst @@ -0,0 +1,1699 @@ +Cassandra Configuration File +===================== + +``cluster_name`` +---------------- +The name of the cluster. This is mainly used to prevent machines in +one logical cluster from joining another. + +*Default Value:* 'Test Cluster' + +``num_tokens`` +-------------- + +This defines the number of tokens randomly assigned to this node on the ring +The more tokens, relative to other nodes, the larger the proportion of data +that this node will store. You probably want all nodes to have the same number +of tokens assuming they have equal hardware capability. + +If you leave this unspecified, Cassandra will use the default of 1 token for legacy compatibility, +and will use the initial_token as described below. + +Specifying initial_token will override this setting on the node's initial start, +on subsequent starts, this setting will apply even if initial token is set. + +If you already have a cluster with 1 token per node, and wish to migrate to +multiple tokens per node, see http://wiki.apache.org/cassandra/Operations + +*Default Value:* 256 + +``allocate_tokens_for_keyspace`` +-------------------------------- +*This option is commented out by default.* + +Triggers automatic allocation of num_tokens tokens for this node. The allocation +algorithm attempts to choose tokens in a way that optimizes replicated load over +the nodes in the datacenter for the replication strategy used by the specified +keyspace. + +The load assigned to each node will be close to proportional to its number of +vnodes. + +Only supported with the Murmur3Partitioner. + +*Default Value:* KEYSPACE + +``initial_token`` +----------------- +*This option is commented out by default.* + +initial_token allows you to specify tokens manually. While you can use it with +vnodes (num_tokens > 1, above) -- in which case you should provide a +comma-separated list -- it's primarily used when adding nodes to legacy clusters +that do not have vnodes enabled. + +``hinted_handoff_enabled`` +-------------------------- + +See http://wiki.apache.org/cassandra/HintedHandoff +May either be "true" or "false" to enable globally + +*Default Value:* true + +``hinted_handoff_disabled_datacenters`` +--------------------------------------- +*This option is commented out by default.* + +When hinted_handoff_enabled is true, a black list of data centers that will not +perform hinted handoff + +*Default Value (complex option)*:: + + # - DC1 + # - DC2 + +``max_hint_window_in_ms`` +------------------------- +this defines the maximum amount of time a dead host will have hints +generated. After it has been dead this long, new hints for it will not be +created until it has been seen alive and gone down again. + +*Default Value:* 10800000 # 3 hours + +``hinted_handoff_throttle_in_kb`` +--------------------------------- + +Maximum throttle in KBs per second, per delivery thread. This will be +reduced proportionally to the number of nodes in the cluster. (If there +are two nodes in the cluster, each delivery thread will use the maximum +rate; if there are three, each will throttle to half of the maximum, +since we expect two nodes to be delivering hints simultaneously.) + +*Default Value:* 1024 + +``max_hints_delivery_threads`` +------------------------------ + +Number of threads with which to deliver hints; +Consider increasing this number when you have multi-dc deployments, since +cross-dc handoff tends to be slower + +*Default Value:* 2 + +``hints_directory`` +------------------- +*This option is commented out by default.* + +Directory where Cassandra should store hints. +If not set, the default directory is $CASSANDRA_HOME/data/hints. + +*Default Value:* /var/lib/cassandra/hints + +``hints_flush_period_in_ms`` +---------------------------- + +How often hints should be flushed from the internal buffers to disk. +Will *not* trigger fsync. + +*Default Value:* 10000 + +``max_hints_file_size_in_mb`` +----------------------------- + +Maximum size for a single hints file, in megabytes. + +*Default Value:* 128 + +``hints_compression`` +--------------------- +*This option is commented out by default.* + +Compression to apply to the hint files. If omitted, hints files +will be written uncompressed. LZ4, Snappy, and Deflate compressors +are supported. + +*Default Value (complex option)*:: + + # - class_name: LZ4Compressor + # parameters: + # - + +``batchlog_replay_throttle_in_kb`` +---------------------------------- +Maximum throttle in KBs per second, total. This will be +reduced proportionally to the number of nodes in the cluster. + +*Default Value:* 1024 + +``authenticator`` +----------------- + +Authentication backend, implementing IAuthenticator; used to identify users +Out of the box, Cassandra provides org.apache.cassandra.auth.{AllowAllAuthenticator, +PasswordAuthenticator}. + +- AllowAllAuthenticator performs no checks - set it to disable authentication. +- PasswordAuthenticator relies on username/password pairs to authenticate + users. It keeps usernames and hashed passwords in system_auth.credentials table. + Please increase system_auth keyspace replication factor if you use this authenticator. + If using PasswordAuthenticator, CassandraRoleManager must also be used (see below) + +*Default Value:* AllowAllAuthenticator + +``authorizer`` +-------------- + +Authorization backend, implementing IAuthorizer; used to limit access/provide permissions +Out of the box, Cassandra provides org.apache.cassandra.auth.{AllowAllAuthorizer, +CassandraAuthorizer}. + +- AllowAllAuthorizer allows any action to any user - set it to disable authorization. +- CassandraAuthorizer stores permissions in system_auth.permissions table. Please + increase system_auth keyspace replication factor if you use this authorizer. + +*Default Value:* AllowAllAuthorizer + +``role_manager`` +---------------- + +Part of the Authentication & Authorization backend, implementing IRoleManager; used +to maintain grants and memberships between roles. +Out of the box, Cassandra provides org.apache.cassandra.auth.CassandraRoleManager, +which stores role information in the system_auth keyspace. Most functions of the +IRoleManager require an authenticated login, so unless the configured IAuthenticator +actually implements authentication, most of this functionality will be unavailable. + +- CassandraRoleManager stores role data in the system_auth keyspace. Please + increase system_auth keyspace replication factor if you use this role manager. + +*Default Value:* CassandraRoleManager + +``roles_validity_in_ms`` +------------------------ + +Validity period for roles cache (fetching granted roles can be an expensive +operation depending on the role manager, CassandraRoleManager is one example) +Granted roles are cached for authenticated sessions in AuthenticatedUser and +after the period specified here, become eligible for (async) reload. +Defaults to 2000, set to 0 to disable caching entirely. +Will be disabled automatically for AllowAllAuthenticator. + +*Default Value:* 2000 + +``roles_update_interval_in_ms`` +------------------------------- +*This option is commented out by default.* + +Refresh interval for roles cache (if enabled). +After this interval, cache entries become eligible for refresh. Upon next +access, an async reload is scheduled and the old value returned until it +completes. If roles_validity_in_ms is non-zero, then this must be +also. +Defaults to the same value as roles_validity_in_ms. + +*Default Value:* 2000 + +``permissions_validity_in_ms`` +------------------------------ + +Validity period for permissions cache (fetching permissions can be an +expensive operation depending on the authorizer, CassandraAuthorizer is +one example). Defaults to 2000, set to 0 to disable. +Will be disabled automatically for AllowAllAuthorizer. + +*Default Value:* 2000 + +``permissions_update_interval_in_ms`` +------------------------------------- +*This option is commented out by default.* + +Refresh interval for permissions cache (if enabled). +After this interval, cache entries become eligible for refresh. Upon next +access, an async reload is scheduled and the old value returned until it +completes. If permissions_validity_in_ms is non-zero, then this must be +also. +Defaults to the same value as permissions_validity_in_ms. + +*Default Value:* 2000 + +``credentials_validity_in_ms`` +------------------------------ + +Validity period for credentials cache. This cache is tightly coupled to +the provided PasswordAuthenticator implementation of IAuthenticator. If +another IAuthenticator implementation is configured, this cache will not +be automatically used and so the following settings will have no effect. +Please note, credentials are cached in their encrypted form, so while +activating this cache may reduce the number of queries made to the +underlying table, it may not bring a significant reduction in the +latency of individual authentication attempts. +Defaults to 2000, set to 0 to disable credentials caching. + +*Default Value:* 2000 + +``credentials_update_interval_in_ms`` +------------------------------------- +*This option is commented out by default.* + +Refresh interval for credentials cache (if enabled). +After this interval, cache entries become eligible for refresh. Upon next +access, an async reload is scheduled and the old value returned until it +completes. If credentials_validity_in_ms is non-zero, then this must be +also. +Defaults to the same value as credentials_validity_in_ms. + +*Default Value:* 2000 + +``partitioner`` +--------------- + +The partitioner is responsible for distributing groups of rows (by +partition key) across nodes in the cluster. You should leave this +alone for new clusters. The partitioner can NOT be changed without +reloading all data, so when upgrading you should set this to the +same partitioner you were already using. + +Besides Murmur3Partitioner, partitioners included for backwards +compatibility include RandomPartitioner, ByteOrderedPartitioner, and +OrderPreservingPartitioner. + + +*Default Value:* org.apache.cassandra.dht.Murmur3Partitioner + +``data_file_directories`` +------------------------- +*This option is commented out by default.* + +Directories where Cassandra should store data on disk. Cassandra +will spread data evenly across them, subject to the granularity of +the configured compaction strategy. +If not set, the default directory is $CASSANDRA_HOME/data/data. + +*Default Value (complex option)*:: + + # - /var/lib/cassandra/data + +``commitlog_directory`` +----------------------- +*This option is commented out by default.* +commit log. when running on magnetic HDD, this should be a +separate spindle than the data directories. +If not set, the default directory is $CASSANDRA_HOME/data/commitlog. + +*Default Value:* /var/lib/cassandra/commitlog + +``disk_failure_policy`` +----------------------- + +Policy for data disk failures: + +die + shut down gossip and client transports and kill the JVM for any fs errors or + single-sstable errors, so the node can be replaced. + +stop_paranoid + shut down gossip and client transports even for single-sstable errors, + kill the JVM for errors during startup. + +stop + shut down gossip and client transports, leaving the node effectively dead, but + can still be inspected via JMX, kill the JVM for errors during startup. + +best_effort + stop using the failed disk and respond to requests based on + remaining available sstables. This means you WILL see obsolete + data at CL.ONE! + +ignore + ignore fatal errors and let requests fail, as in pre-1.2 Cassandra + +*Default Value:* stop + +``commit_failure_policy`` +------------------------- + +Policy for commit disk failures: + +die + shut down gossip and Thrift and kill the JVM, so the node can be replaced. + +stop + shut down gossip and Thrift, leaving the node effectively dead, but + can still be inspected via JMX. + +stop_commit + shutdown the commit log, letting writes collect but + continuing to service reads, as in pre-2.0.5 Cassandra + +ignore + ignore fatal errors and let the batches fail + +*Default Value:* stop + +``prepared_statements_cache_size_mb`` +------------------------------------- + +Maximum size of the native protocol prepared statement cache + +Valid values are either "auto" (omitting the value) or a value greater 0. + +Note that specifying a too large value will result in long running GCs and possbily +out-of-memory errors. Keep the value at a small fraction of the heap. + +If you constantly see "prepared statements discarded in the last minute because +cache limit reached" messages, the first step is to investigate the root cause +of these messages and check whether prepared statements are used correctly - +i.e. use bind markers for variable parts. + +Do only change the default value, if you really have more prepared statements than +fit in the cache. In most cases it is not neccessary to change this value. +Constantly re-preparing statements is a performance penalty. + +Default value ("auto") is 1/256th of the heap or 10MB, whichever is greater + +``thrift_prepared_statements_cache_size_mb`` +-------------------------------------------- + +Maximum size of the Thrift prepared statement cache + +If you do not use Thrift at all, it is safe to leave this value at "auto". + +See description of 'prepared_statements_cache_size_mb' above for more information. + +Default value ("auto") is 1/256th of the heap or 10MB, whichever is greater + +``key_cache_size_in_mb`` +------------------------ + +Maximum size of the key cache in memory. + +Each key cache hit saves 1 seek and each row cache hit saves 2 seeks at the +minimum, sometimes more. The key cache is fairly tiny for the amount of +time it saves, so it's worthwhile to use it at large numbers. +The row cache saves even more time, but must contain the entire row, +so it is extremely space-intensive. It's best to only use the +row cache if you have hot rows or static rows. + +NOTE: if you reduce the size, you may not get you hottest keys loaded on startup. + +Default value is empty to make it "auto" (min(5% of Heap (in MB), 100MB)). Set to 0 to disable key cache. + +``key_cache_save_period`` +------------------------- + +Duration in seconds after which Cassandra should +save the key cache. Caches are saved to saved_caches_directory as +specified in this configuration file. + +Saved caches greatly improve cold-start speeds, and is relatively cheap in +terms of I/O for the key cache. Row cache saving is much more expensive and +has limited use. + +Default is 14400 or 4 hours. + +*Default Value:* 14400 + +``key_cache_keys_to_save`` +-------------------------- +*This option is commented out by default.* + +Number of keys from the key cache to save +Disabled by default, meaning all keys are going to be saved + +*Default Value:* 100 + +``row_cache_class_name`` +------------------------ +*This option is commented out by default.* + +Row cache implementation class name. Available implementations: + +org.apache.cassandra.cache.OHCProvider + Fully off-heap row cache implementation (default). + +org.apache.cassandra.cache.SerializingCacheProvider + This is the row cache implementation availabile + in previous releases of Cassandra. + +*Default Value:* org.apache.cassandra.cache.OHCProvider + +``row_cache_size_in_mb`` +------------------------ + +Maximum size of the row cache in memory. +Please note that OHC cache implementation requires some additional off-heap memory to manage +the map structures and some in-flight memory during operations before/after cache entries can be +accounted against the cache capacity. This overhead is usually small compared to the whole capacity. +Do not specify more memory that the system can afford in the worst usual situation and leave some +headroom for OS block level cache. Do never allow your system to swap. + +Default value is 0, to disable row caching. + +*Default Value:* 0 + +``row_cache_save_period`` +------------------------- + +Duration in seconds after which Cassandra should save the row cache. +Caches are saved to saved_caches_directory as specified in this configuration file. + +Saved caches greatly improve cold-start speeds, and is relatively cheap in +terms of I/O for the key cache. Row cache saving is much more expensive and +has limited use. + +Default is 0 to disable saving the row cache. + +*Default Value:* 0 + +``row_cache_keys_to_save`` +-------------------------- +*This option is commented out by default.* + +Number of keys from the row cache to save. +Specify 0 (which is the default), meaning all keys are going to be saved + +*Default Value:* 100 + +``counter_cache_size_in_mb`` +---------------------------- + +Maximum size of the counter cache in memory. + +Counter cache helps to reduce counter locks' contention for hot counter cells. +In case of RF = 1 a counter cache hit will cause Cassandra to skip the read before +write entirely. With RF > 1 a counter cache hit will still help to reduce the duration +of the lock hold, helping with hot counter cell updates, but will not allow skipping +the read entirely. Only the local (clock, count) tuple of a counter cell is kept +in memory, not the whole counter, so it's relatively cheap. + +NOTE: if you reduce the size, you may not get you hottest keys loaded on startup. + +Default value is empty to make it "auto" (min(2.5% of Heap (in MB), 50MB)). Set to 0 to disable counter cache. +NOTE: if you perform counter deletes and rely on low gcgs, you should disable the counter cache. + +``counter_cache_save_period`` +----------------------------- + +Duration in seconds after which Cassandra should +save the counter cache (keys only). Caches are saved to saved_caches_directory as +specified in this configuration file. + +Default is 7200 or 2 hours. + +*Default Value:* 7200 + +``counter_cache_keys_to_save`` +------------------------------ +*This option is commented out by default.* + +Number of keys from the counter cache to save +Disabled by default, meaning all keys are going to be saved + +*Default Value:* 100 + +``saved_caches_directory`` +-------------------------- +*This option is commented out by default.* + +saved caches +If not set, the default directory is $CASSANDRA_HOME/data/saved_caches. + +*Default Value:* /var/lib/cassandra/saved_caches + +``commitlog_sync`` +------------------ +*This option is commented out by default.* + +commitlog_sync may be either "periodic" or "batch." + +When in batch mode, Cassandra won't ack writes until the commit log +has been fsynced to disk. It will wait +commitlog_sync_batch_window_in_ms milliseconds between fsyncs. +This window should be kept short because the writer threads will +be unable to do extra work while waiting. (You may need to increase +concurrent_writes for the same reason.) + + +*Default Value:* batch + +``commitlog_sync_batch_window_in_ms`` +------------------------------------- +*This option is commented out by default.* + +*Default Value:* 2 + +``commitlog_sync`` +------------------ + +the other option is "periodic" where writes may be acked immediately +and the CommitLog is simply synced every commitlog_sync_period_in_ms +milliseconds. + +*Default Value:* periodic + +``commitlog_sync_period_in_ms`` +------------------------------- + +*Default Value:* 10000 + +``commitlog_segment_size_in_mb`` +-------------------------------- + +The size of the individual commitlog file segments. A commitlog +segment may be archived, deleted, or recycled once all the data +in it (potentially from each columnfamily in the system) has been +flushed to sstables. + +The default size is 32, which is almost always fine, but if you are +archiving commitlog segments (see commitlog_archiving.properties), +then you probably want a finer granularity of archiving; 8 or 16 MB +is reasonable. +Max mutation size is also configurable via max_mutation_size_in_kb setting in +cassandra.yaml. The default is half the size commitlog_segment_size_in_mb * 1024. + +NOTE: If max_mutation_size_in_kb is set explicitly then commitlog_segment_size_in_mb must +be set to at least twice the size of max_mutation_size_in_kb / 1024 + + +*Default Value:* 32 + +``commitlog_compression`` +------------------------- +*This option is commented out by default.* + +Compression to apply to the commit log. If omitted, the commit log +will be written uncompressed. LZ4, Snappy, and Deflate compressors +are supported. + +*Default Value (complex option)*:: + + # - class_name: LZ4Compressor + # parameters: + # - + +``seed_provider`` +----------------- +any class that implements the SeedProvider interface and has a +constructor that takes a Map of parameters will do. + +*Default Value (complex option)*:: + + # Addresses of hosts that are deemed contact points. + # Cassandra nodes use this list of hosts to find each other and learn + # the topology of the ring. You must change this if you are running + # multiple nodes! + - class_name: org.apache.cassandra.locator.SimpleSeedProvider + parameters: + # seeds is actually a comma-delimited list of addresses. + # Ex: ",," + - seeds: "127.0.0.1" + +``concurrent_reads`` +-------------------- +For workloads with more data than can fit in memory, Cassandra's +bottleneck will be reads that need to fetch data from +disk. "concurrent_reads" should be set to (16 * number_of_drives) in +order to allow the operations to enqueue low enough in the stack +that the OS and drives can reorder them. Same applies to +"concurrent_counter_writes", since counter writes read the current +values before incrementing and writing them back. + +On the other hand, since writes are almost never IO bound, the ideal +number of "concurrent_writes" is dependent on the number of cores in +your system; (8 * number_of_cores) is a good rule of thumb. + +*Default Value:* 32 + +``concurrent_writes`` +--------------------- + +*Default Value:* 32 + +``concurrent_counter_writes`` +----------------------------- + +*Default Value:* 32 + +``concurrent_materialized_view_writes`` +--------------------------------------- + +For materialized view writes, as there is a read involved, so this should +be limited by the less of concurrent reads or concurrent writes. + +*Default Value:* 32 + +``file_cache_size_in_mb`` +------------------------- +*This option is commented out by default.* + +Maximum memory to use for sstable chunk cache and buffer pooling. +32MB of this are reserved for pooling buffers, the rest is used as an +cache that holds uncompressed sstable chunks. +Defaults to the smaller of 1/4 of heap or 512MB. This pool is allocated off-heap, +so is in addition to the memory allocated for heap. The cache also has on-heap +overhead which is roughly 128 bytes per chunk (i.e. 0.2% of the reserved size +if the default 64k chunk size is used). +Memory is only allocated when needed. + +*Default Value:* 512 + +``buffer_pool_use_heap_if_exhausted`` +------------------------------------- +*This option is commented out by default.* + +Flag indicating whether to allocate on or off heap when the sstable buffer +pool is exhausted, that is when it has exceeded the maximum memory +file_cache_size_in_mb, beyond which it will not cache buffers but allocate on request. + + +*Default Value:* true + +``disk_optimization_strategy`` +------------------------------ +*This option is commented out by default.* + +The strategy for optimizing disk read +Possible values are: +ssd (for solid state disks, the default) +spinning (for spinning disks) + +*Default Value:* ssd + +``memtable_heap_space_in_mb`` +----------------------------- +*This option is commented out by default.* + +Total permitted memory to use for memtables. Cassandra will stop +accepting writes when the limit is exceeded until a flush completes, +and will trigger a flush based on memtable_cleanup_threshold +If omitted, Cassandra will set both to 1/4 the size of the heap. + +*Default Value:* 2048 + +``memtable_offheap_space_in_mb`` +-------------------------------- +*This option is commented out by default.* + +*Default Value:* 2048 + +``memtable_cleanup_threshold`` +------------------------------ +*This option is commented out by default.* + +Ratio of occupied non-flushing memtable size to total permitted size +that will trigger a flush of the largest memtable. Larger mct will +mean larger flushes and hence less compaction, but also less concurrent +flush activity which can make it difficult to keep your disks fed +under heavy write load. + +memtable_cleanup_threshold defaults to 1 / (memtable_flush_writers + 1) + +*Default Value:* 0.11 + +``memtable_allocation_type`` +---------------------------- + +Specify the way Cassandra allocates and manages memtable memory. +Options are: + +heap_buffers + on heap nio buffers + +offheap_buffers + off heap (direct) nio buffers + +offheap_objects + off heap objects + +*Default Value:* heap_buffers + +``commitlog_total_space_in_mb`` +------------------------------- +*This option is commented out by default.* + +Total space to use for commit logs on disk. + +If space gets above this value, Cassandra will flush every dirty CF +in the oldest segment and remove it. So a small total commitlog space +will tend to cause more flush activity on less-active columnfamilies. + +The default value is the smaller of 8192, and 1/4 of the total space +of the commitlog volume. + + +*Default Value:* 8192 + +``memtable_flush_writers`` +-------------------------- +*This option is commented out by default.* + +This sets the amount of memtable flush writer threads. These will +be blocked by disk io, and each one will hold a memtable in memory +while blocked. + +memtable_flush_writers defaults to one per data_file_directory. + +If your data directories are backed by SSD, you can increase this, but +avoid having memtable_flush_writers * data_file_directories > number of cores + +*Default Value:* 1 + +``index_summary_capacity_in_mb`` +-------------------------------- + +A fixed memory pool size in MB for for SSTable index summaries. If left +empty, this will default to 5% of the heap size. If the memory usage of +all index summaries exceeds this limit, SSTables with low read rates will +shrink their index summaries in order to meet this limit. However, this +is a best-effort process. In extreme conditions Cassandra may need to use +more than this amount of memory. + +``index_summary_resize_interval_in_minutes`` +-------------------------------------------- + +How frequently index summaries should be resampled. This is done +periodically to redistribute memory from the fixed-size pool to sstables +proportional their recent read rates. Setting to -1 will disable this +process, leaving existing index summaries at their current sampling level. + +*Default Value:* 60 + +``trickle_fsync`` +----------------- + +Whether to, when doing sequential writing, fsync() at intervals in +order to force the operating system to flush the dirty +buffers. Enable this to avoid sudden dirty buffer flushing from +impacting read latencies. Almost always a good idea on SSDs; not +necessarily on platters. + +*Default Value:* false + +``trickle_fsync_interval_in_kb`` +-------------------------------- + +*Default Value:* 10240 + +``storage_port`` +---------------- + +TCP port, for commands and data +For security reasons, you should not expose this port to the internet. Firewall it if needed. + +*Default Value:* 7000 + +``ssl_storage_port`` +-------------------- + +SSL port, for encrypted communication. Unused unless enabled in +encryption_options +For security reasons, you should not expose this port to the internet. Firewall it if needed. + +*Default Value:* 7001 + +``listen_address`` +------------------ + +Address or interface to bind to and tell other Cassandra nodes to connect to. +You _must_ change this if you want multiple nodes to be able to communicate! + +Set listen_address OR listen_interface, not both. + +Leaving it blank leaves it up to InetAddress.getLocalHost(). This +will always do the Right Thing _if_ the node is properly configured +(hostname, name resolution, etc), and the Right Thing is to use the +address associated with the hostname (it might not be). + +Setting listen_address to 0.0.0.0 is always wrong. + + +*Default Value:* localhost + +``listen_interface`` +-------------------- +*This option is commented out by default.* + +Set listen_address OR listen_interface, not both. Interfaces must correspond +to a single address, IP aliasing is not supported. + +*Default Value:* eth0 + +``listen_interface_prefer_ipv6`` +-------------------------------- +*This option is commented out by default.* + +If you choose to specify the interface by name and the interface has an ipv4 and an ipv6 address +you can specify which should be chosen using listen_interface_prefer_ipv6. If false the first ipv4 +address will be used. If true the first ipv6 address will be used. Defaults to false preferring +ipv4. If there is only one address it will be selected regardless of ipv4/ipv6. + +*Default Value:* false + +``broadcast_address`` +--------------------- +*This option is commented out by default.* + +Address to broadcast to other Cassandra nodes +Leaving this blank will set it to the same value as listen_address + +*Default Value:* 1.2.3.4 + +``listen_on_broadcast_address`` +------------------------------- +*This option is commented out by default.* + +When using multiple physical network interfaces, set this +to true to listen on broadcast_address in addition to +the listen_address, allowing nodes to communicate in both +interfaces. +Ignore this property if the network configuration automatically +routes between the public and private networks such as EC2. + +*Default Value:* false + +``internode_authenticator`` +--------------------------- +*This option is commented out by default.* + +Internode authentication backend, implementing IInternodeAuthenticator; +used to allow/disallow connections from peer nodes. + +*Default Value:* org.apache.cassandra.auth.AllowAllInternodeAuthenticator + +``start_native_transport`` +-------------------------- + +Whether to start the native transport server. +Please note that the address on which the native transport is bound is the +same as the rpc_address. The port however is different and specified below. + +*Default Value:* true + +``native_transport_port`` +------------------------- +port for the CQL native transport to listen for clients on +For security reasons, you should not expose this port to the internet. Firewall it if needed. + +*Default Value:* 9042 + +``native_transport_port_ssl`` +----------------------------- +*This option is commented out by default.* +Enabling native transport encryption in client_encryption_options allows you to either use +encryption for the standard port or to use a dedicated, additional port along with the unencrypted +standard native_transport_port. +Enabling client encryption and keeping native_transport_port_ssl disabled will use encryption +for native_transport_port. Setting native_transport_port_ssl to a different value +from native_transport_port will use encryption for native_transport_port_ssl while +keeping native_transport_port unencrypted. + +*Default Value:* 9142 + +``native_transport_max_threads`` +-------------------------------- +*This option is commented out by default.* +The maximum threads for handling requests when the native transport is used. +This is similar to rpc_max_threads though the default differs slightly (and +there is no native_transport_min_threads, idle threads will always be stopped +after 30 seconds). + +*Default Value:* 128 + +``native_transport_max_frame_size_in_mb`` +----------------------------------------- +*This option is commented out by default.* + +The maximum size of allowed frame. Frame (requests) larger than this will +be rejected as invalid. The default is 256MB. If you're changing this parameter, +you may want to adjust max_value_size_in_mb accordingly. + +*Default Value:* 256 + +``native_transport_max_concurrent_connections`` +----------------------------------------------- +*This option is commented out by default.* + +The maximum number of concurrent client connections. +The default is -1, which means unlimited. + +*Default Value:* -1 + +``native_transport_max_concurrent_connections_per_ip`` +------------------------------------------------------ +*This option is commented out by default.* + +The maximum number of concurrent client connections per source ip. +The default is -1, which means unlimited. + +*Default Value:* -1 + +``start_rpc`` +------------- + +Whether to start the thrift rpc server. + +*Default Value:* false + +``rpc_address`` +--------------- + +The address or interface to bind the Thrift RPC service and native transport +server to. + +Set rpc_address OR rpc_interface, not both. + +Leaving rpc_address blank has the same effect as on listen_address +(i.e. it will be based on the configured hostname of the node). + +Note that unlike listen_address, you can specify 0.0.0.0, but you must also +set broadcast_rpc_address to a value other than 0.0.0.0. + +For security reasons, you should not expose this port to the internet. Firewall it if needed. + +*Default Value:* localhost + +``rpc_interface`` +----------------- +*This option is commented out by default.* + +Set rpc_address OR rpc_interface, not both. Interfaces must correspond +to a single address, IP aliasing is not supported. + +*Default Value:* eth1 + +``rpc_interface_prefer_ipv6`` +----------------------------- +*This option is commented out by default.* + +If you choose to specify the interface by name and the interface has an ipv4 and an ipv6 address +you can specify which should be chosen using rpc_interface_prefer_ipv6. If false the first ipv4 +address will be used. If true the first ipv6 address will be used. Defaults to false preferring +ipv4. If there is only one address it will be selected regardless of ipv4/ipv6. + +*Default Value:* false + +``rpc_port`` +------------ + +port for Thrift to listen for clients on + +*Default Value:* 9160 + +``broadcast_rpc_address`` +------------------------- +*This option is commented out by default.* + +RPC address to broadcast to drivers and other Cassandra nodes. This cannot +be set to 0.0.0.0. If left blank, this will be set to the value of +rpc_address. If rpc_address is set to 0.0.0.0, broadcast_rpc_address must +be set. + +*Default Value:* 1.2.3.4 + +``rpc_keepalive`` +----------------- + +enable or disable keepalive on rpc/native connections + +*Default Value:* true + +``rpc_server_type`` +------------------- + +Cassandra provides two out-of-the-box options for the RPC Server: + +sync + One thread per thrift connection. For a very large number of clients, memory + will be your limiting factor. On a 64 bit JVM, 180KB is the minimum stack size + per thread, and that will correspond to your use of virtual memory (but physical memory + may be limited depending on use of stack space). + +hsha + Stands for "half synchronous, half asynchronous." All thrift clients are handled + asynchronously using a small number of threads that does not vary with the amount + of thrift clients (and thus scales well to many clients). The rpc requests are still + synchronous (one thread per active request). If hsha is selected then it is essential + that rpc_max_threads is changed from the default value of unlimited. + +The default is sync because on Windows hsha is about 30% slower. On Linux, +sync/hsha performance is about the same, with hsha of course using less memory. + +Alternatively, can provide your own RPC server by providing the fully-qualified class name +of an o.a.c.t.TServerFactory that can create an instance of it. + +*Default Value:* sync + +``rpc_min_threads`` +------------------- +*This option is commented out by default.* + +Uncomment rpc_min|max_thread to set request pool size limits. + +Regardless of your choice of RPC server (see above), the number of maximum requests in the +RPC thread pool dictates how many concurrent requests are possible (but if you are using the sync +RPC server, it also dictates the number of clients that can be connected at all). + +The default is unlimited and thus provides no protection against clients overwhelming the server. You are +encouraged to set a maximum that makes sense for you in production, but do keep in mind that +rpc_max_threads represents the maximum number of client requests this server may execute concurrently. + + +*Default Value:* 16 + +``rpc_max_threads`` +------------------- +*This option is commented out by default.* + +*Default Value:* 2048 + +``rpc_send_buff_size_in_bytes`` +------------------------------- +*This option is commented out by default.* + +uncomment to set socket buffer sizes on rpc connections + +``rpc_recv_buff_size_in_bytes`` +------------------------------- +*This option is commented out by default.* + +``internode_send_buff_size_in_bytes`` +------------------------------------- +*This option is commented out by default.* + +Uncomment to set socket buffer size for internode communication +Note that when setting this, the buffer size is limited by net.core.wmem_max +and when not setting it it is defined by net.ipv4.tcp_wmem +See also: +/proc/sys/net/core/wmem_max +/proc/sys/net/core/rmem_max +/proc/sys/net/ipv4/tcp_wmem +/proc/sys/net/ipv4/tcp_wmem +and 'man tcp' + +``internode_recv_buff_size_in_bytes`` +------------------------------------- +*This option is commented out by default.* + +Uncomment to set socket buffer size for internode communication +Note that when setting this, the buffer size is limited by net.core.wmem_max +and when not setting it it is defined by net.ipv4.tcp_wmem + +``thrift_framed_transport_size_in_mb`` +-------------------------------------- + +Frame size for thrift (maximum message length). + +*Default Value:* 15 + +``incremental_backups`` +----------------------- + +Set to true to have Cassandra create a hard link to each sstable +flushed or streamed locally in a backups/ subdirectory of the +keyspace data. Removing these links is the operator's +responsibility. + +*Default Value:* false + +``snapshot_before_compaction`` +------------------------------ + +Whether or not to take a snapshot before each compaction. Be +careful using this option, since Cassandra won't clean up the +snapshots for you. Mostly useful if you're paranoid when there +is a data format change. + +*Default Value:* false + +``auto_snapshot`` +----------------- + +Whether or not a snapshot is taken of the data before keyspace truncation +or dropping of column families. The STRONGLY advised default of true +should be used to provide data safety. If you set this flag to false, you will +lose data on truncation or drop. + +*Default Value:* true + +``column_index_size_in_kb`` +--------------------------- + +Granularity of the collation index of rows within a partition. +Increase if your rows are large, or if you have a very large +number of rows per partition. The competing goals are these: + +- a smaller granularity means more index entries are generated + and looking up rows withing the partition by collation column + is faster +- but, Cassandra will keep the collation index in memory for hot + rows (as part of the key cache), so a larger granularity means + you can cache more hot rows + +*Default Value:* 64 + +``column_index_cache_size_in_kb`` +--------------------------------- + +Per sstable indexed key cache entries (the collation index in memory +mentioned above) exceeding this size will not be held on heap. +This means that only partition information is held on heap and the +index entries are read from disk. + +Note that this size refers to the size of the +serialized index information and not the size of the partition. + +*Default Value:* 2 + +``concurrent_compactors`` +------------------------- +*This option is commented out by default.* + +Number of simultaneous compactions to allow, NOT including +validation "compactions" for anti-entropy repair. Simultaneous +compactions can help preserve read performance in a mixed read/write +workload, by mitigating the tendency of small sstables to accumulate +during a single long running compactions. The default is usually +fine and if you experience problems with compaction running too +slowly or too fast, you should look at +compaction_throughput_mb_per_sec first. + +concurrent_compactors defaults to the smaller of (number of disks, +number of cores), with a minimum of 2 and a maximum of 8. + +If your data directories are backed by SSD, you should increase this +to the number of cores. + +*Default Value:* 1 + +``compaction_throughput_mb_per_sec`` +------------------------------------ + +Throttles compaction to the given total throughput across the entire +system. The faster you insert data, the faster you need to compact in +order to keep the sstable count down, but in general, setting this to +16 to 32 times the rate you are inserting data is more than sufficient. +Setting this to 0 disables throttling. Note that this account for all types +of compaction, including validation compaction. + +*Default Value:* 16 + +``sstable_preemptive_open_interval_in_mb`` +------------------------------------------ + +When compacting, the replacement sstable(s) can be opened before they +are completely written, and used in place of the prior sstables for +any range that has been written. This helps to smoothly transfer reads +between the sstables, reducing page cache churn and keeping hot rows hot + +*Default Value:* 50 + +``stream_throughput_outbound_megabits_per_sec`` +----------------------------------------------- +*This option is commented out by default.* + +Throttles all outbound streaming file transfers on this node to the +given total throughput in Mbps. This is necessary because Cassandra does +mostly sequential IO when streaming data during bootstrap or repair, which +can lead to saturating the network connection and degrading rpc performance. +When unset, the default is 200 Mbps or 25 MB/s. + +*Default Value:* 200 + +``inter_dc_stream_throughput_outbound_megabits_per_sec`` +-------------------------------------------------------- +*This option is commented out by default.* + +Throttles all streaming file transfer between the datacenters, +this setting allows users to throttle inter dc stream throughput in addition +to throttling all network stream traffic as configured with +stream_throughput_outbound_megabits_per_sec +When unset, the default is 200 Mbps or 25 MB/s + +*Default Value:* 200 + +``read_request_timeout_in_ms`` +------------------------------ + +How long the coordinator should wait for read operations to complete + +*Default Value:* 5000 + +``range_request_timeout_in_ms`` +------------------------------- +How long the coordinator should wait for seq or index scans to complete + +*Default Value:* 10000 + +``write_request_timeout_in_ms`` +------------------------------- +How long the coordinator should wait for writes to complete + +*Default Value:* 2000 + +``counter_write_request_timeout_in_ms`` +--------------------------------------- +How long the coordinator should wait for counter writes to complete + +*Default Value:* 5000 + +``cas_contention_timeout_in_ms`` +-------------------------------- +How long a coordinator should continue to retry a CAS operation +that contends with other proposals for the same row + +*Default Value:* 1000 + +``truncate_request_timeout_in_ms`` +---------------------------------- +How long the coordinator should wait for truncates to complete +(This can be much longer, because unless auto_snapshot is disabled +we need to flush first so we can snapshot before removing the data.) + +*Default Value:* 60000 + +``request_timeout_in_ms`` +------------------------- +The default timeout for other, miscellaneous operations + +*Default Value:* 10000 + +``cross_node_timeout`` +---------------------- + +Enable operation timeout information exchange between nodes to accurately +measure request timeouts. If disabled, replicas will assume that requests +were forwarded to them instantly by the coordinator, which means that +under overload conditions we will waste that much extra time processing +already-timed-out requests. + +Warning: before enabling this property make sure to ntp is installed +and the times are synchronized between the nodes. + +*Default Value:* false + +``streaming_socket_timeout_in_ms`` +---------------------------------- +*This option is commented out by default.* + +Set socket timeout for streaming operation. +The stream session is failed if no data/ack is received by any of the participants +within that period, which means this should also be sufficient to stream a large +sstable or rebuild table indexes. +Default value is 86400000ms, which means stale streams timeout after 24 hours. +A value of zero means stream sockets should never time out. + +*Default Value:* 86400000 + +``phi_convict_threshold`` +------------------------- +*This option is commented out by default.* + +phi value that must be reached for a host to be marked down. +most users should never need to adjust this. + +*Default Value:* 8 + +``endpoint_snitch`` +------------------- + +endpoint_snitch -- Set this to a class that implements +IEndpointSnitch. The snitch has two functions: + +- it teaches Cassandra enough about your network topology to route + requests efficiently +- it allows Cassandra to spread replicas around your cluster to avoid + correlated failures. It does this by grouping machines into + "datacenters" and "racks." Cassandra will do its best not to have + more than one replica on the same "rack" (which may not actually + be a physical location) + +IF YOU CHANGE THE SNITCH AFTER DATA IS INSERTED INTO THE CLUSTER, +YOU MUST RUN A FULL REPAIR, SINCE THE SNITCH AFFECTS WHERE REPLICAS +ARE PLACED. + +IF THE RACK A REPLICA IS PLACED IN CHANGES AFTER THE REPLICA HAS BEEN +ADDED TO A RING, THE NODE MUST BE DECOMMISSIONED AND REBOOTSTRAPPED. + +Out of the box, Cassandra provides: + +SimpleSnitch: + Treats Strategy order as proximity. This can improve cache + locality when disabling read repair. Only appropriate for + single-datacenter deployments. + +GossipingPropertyFileSnitch + This should be your go-to snitch for production use. The rack + and datacenter for the local node are defined in + cassandra-rackdc.properties and propagated to other nodes via + gossip. If cassandra-topology.properties exists, it is used as a + fallback, allowing migration from the PropertyFileSnitch. + +PropertyFileSnitch: + Proximity is determined by rack and data center, which are + explicitly configured in cassandra-topology.properties. + +Ec2Snitch: + Appropriate for EC2 deployments in a single Region. Loads Region + and Availability Zone information from the EC2 API. The Region is + treated as the datacenter, and the Availability Zone as the rack. + Only private IPs are used, so this will not work across multiple + Regions. + +Ec2MultiRegionSnitch: + Uses public IPs as broadcast_address to allow cross-region + connectivity. (Thus, you should set seed addresses to the public + IP as well.) You will need to open the storage_port or + ssl_storage_port on the public IP firewall. (For intra-Region + traffic, Cassandra will switch to the private IP after + establishing a connection.) + +RackInferringSnitch: + Proximity is determined by rack and data center, which are + assumed to correspond to the 3rd and 2nd octet of each node's IP + address, respectively. Unless this happens to match your + deployment conventions, this is best used as an example of + writing a custom Snitch class and is provided in that spirit. + +You can use a custom Snitch by setting this to the full class name +of the snitch, which will be assumed to be on your classpath. + +*Default Value:* SimpleSnitch + +``dynamic_snitch_update_interval_in_ms`` +---------------------------------------- + +controls how often to perform the more expensive part of host score +calculation + +*Default Value:* 100 + +``dynamic_snitch_reset_interval_in_ms`` +--------------------------------------- +controls how often to reset all host scores, allowing a bad host to +possibly recover + +*Default Value:* 600000 + +``dynamic_snitch_badness_threshold`` +------------------------------------ +if set greater than zero and read_repair_chance is < 1.0, this will allow +'pinning' of replicas to hosts in order to increase cache capacity. +The badness threshold will control how much worse the pinned host has to be +before the dynamic snitch will prefer other replicas over it. This is +expressed as a double which represents a percentage. Thus, a value of +0.2 means Cassandra would continue to prefer the static snitch values +until the pinned host was 20% worse than the fastest. + +*Default Value:* 0.1 + +``request_scheduler`` +--------------------- + +request_scheduler -- Set this to a class that implements +RequestScheduler, which will schedule incoming client requests +according to the specific policy. This is useful for multi-tenancy +with a single Cassandra cluster. +NOTE: This is specifically for requests from the client and does +not affect inter node communication. +org.apache.cassandra.scheduler.NoScheduler - No scheduling takes place +org.apache.cassandra.scheduler.RoundRobinScheduler - Round robin of +client requests to a node with a separate queue for each +request_scheduler_id. The scheduler is further customized by +request_scheduler_options as described below. + +*Default Value:* org.apache.cassandra.scheduler.NoScheduler + +``request_scheduler_options`` +----------------------------- +*This option is commented out by default.* + +Scheduler Options vary based on the type of scheduler + +NoScheduler + Has no options + +RoundRobin + throttle_limit + The throttle_limit is the number of in-flight + requests per client. Requests beyond + that limit are queued up until + running requests can complete. + The value of 80 here is twice the number of + concurrent_reads + concurrent_writes. + default_weight + default_weight is optional and allows for + overriding the default which is 1. + weights + Weights are optional and will default to 1 or the + overridden default_weight. The weight translates into how + many requests are handled during each turn of the + RoundRobin, based on the scheduler id. + + +*Default Value (complex option)*:: + + # throttle_limit: 80 + # default_weight: 5 + # weights: + # Keyspace1: 1 + # Keyspace2: 5 + +``request_scheduler_id`` +------------------------ +*This option is commented out by default.* +request_scheduler_id -- An identifier based on which to perform +the request scheduling. Currently the only valid option is keyspace. + +*Default Value:* keyspace + +``server_encryption_options`` +----------------------------- + +Enable or disable inter-node encryption +JVM defaults for supported SSL socket protocols and cipher suites can +be replaced using custom encryption options. This is not recommended +unless you have policies in place that dictate certain settings, or +need to disable vulnerable ciphers or protocols in case the JVM cannot +be updated. +FIPS compliant settings can be configured at JVM level and should not +involve changing encryption settings here: +https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/FIPS.html +*NOTE* No custom encryption options are enabled at the moment +The available internode options are : all, none, dc, rack + +If set to dc cassandra will encrypt the traffic between the DCs +If set to rack cassandra will encrypt the traffic between the racks + +The passwords used in these options must match the passwords used when generating +the keystore and truststore. For instructions on generating these files, see: +http://download.oracle.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuide.html#CreateKeystore + + +*Default Value (complex option)*:: + + internode_encryption: none + keystore: conf/.keystore + keystore_password: cassandra + truststore: conf/.truststore + truststore_password: cassandra + # More advanced defaults below: + # protocol: TLS + # algorithm: SunX509 + # store_type: JKS + # cipher_suites: [TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_DHE_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA] + # require_client_auth: false + # require_endpoint_verification: false + +``client_encryption_options`` +----------------------------- +enable or disable client/server encryption. + +*Default Value (complex option)*:: + + enabled: false + # If enabled and optional is set to true encrypted and unencrypted connections are handled. + optional: false + keystore: conf/.keystore + keystore_password: cassandra + # require_client_auth: false + # Set trustore and truststore_password if require_client_auth is true + # truststore: conf/.truststore + # truststore_password: cassandra + # More advanced defaults below: + # protocol: TLS + # algorithm: SunX509 + # store_type: JKS + # cipher_suites: [TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_DHE_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA] + +``internode_compression`` +------------------------- +internode_compression controls whether traffic between nodes is +compressed. +Can be: + +all + all traffic is compressed + +dc + traffic between different datacenters is compressed + +none + nothing is compressed. + +*Default Value:* dc + +``inter_dc_tcp_nodelay`` +------------------------ + +Enable or disable tcp_nodelay for inter-dc communication. +Disabling it will result in larger (but fewer) network packets being sent, +reducing overhead from the TCP protocol itself, at the cost of increasing +latency if you block for cross-datacenter responses. + +*Default Value:* false + +``tracetype_query_ttl`` +----------------------- + +TTL for different trace types used during logging of the repair process. + +*Default Value:* 86400 + +``tracetype_repair_ttl`` +------------------------ + +*Default Value:* 604800 + +``enable_user_defined_functions`` +--------------------------------- + +UDFs (user defined functions) are disabled by default. +As of Cassandra 3.0 there is a sandbox in place that should prevent execution of evil code. + +*Default Value:* false + +``enable_scripted_user_defined_functions`` +------------------------------------------ + +Enables scripted UDFs (JavaScript UDFs). +Java UDFs are always enabled, if enable_user_defined_functions is true. +Enable this option to be able to use UDFs with "language javascript" or any custom JSR-223 provider. +This option has no effect, if enable_user_defined_functions is false. + +*Default Value:* false + +``windows_timer_interval`` +-------------------------- + +The default Windows kernel timer and scheduling resolution is 15.6ms for power conservation. +Lowering this value on Windows can provide much tighter latency and better throughput, however +some virtualized environments may see a negative performance impact from changing this setting +below their system default. The sysinternals 'clockres' tool can confirm your system's default +setting. + +*Default Value:* 1 + +``transparent_data_encryption_options`` +--------------------------------------- + + +Enables encrypting data at-rest (on disk). Different key providers can be plugged in, but the default reads from +a JCE-style keystore. A single keystore can hold multiple keys, but the one referenced by +the "key_alias" is the only key that will be used for encrypt opertaions; previously used keys +can still (and should!) be in the keystore and will be used on decrypt operations +(to handle the case of key rotation). + +It is strongly recommended to download and install Java Cryptography Extension (JCE) +Unlimited Strength Jurisdiction Policy Files for your version of the JDK. +(current link: http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html) + +Currently, only the following file types are supported for transparent data encryption, although +more are coming in future cassandra releases: commitlog, hints + +*Default Value (complex option)*:: + + enabled: false + chunk_length_kb: 64 + cipher: AES/CBC/PKCS5Padding + key_alias: testing:1 + # CBC IV length for AES needs to be 16 bytes (which is also the default size) + # iv_length: 16 + key_provider: + - class_name: org.apache.cassandra.security.JKSKeyProvider + parameters: + - keystore: conf/.keystore + keystore_password: cassandra + store_type: JCEKS + key_password: cassandra + +``tombstone_warn_threshold`` +---------------------------- + +#################### +SAFETY THRESHOLDS # +#################### + +When executing a scan, within or across a partition, we need to keep the +tombstones seen in memory so we can return them to the coordinator, which +will use them to make sure other replicas also know about the deleted rows. +With workloads that generate a lot of tombstones, this can cause performance +problems and even exaust the server heap. +(http://www.datastax.com/dev/blog/cassandra-anti-patterns-queues-and-queue-like-datasets) +Adjust the thresholds here if you understand the dangers and want to +scan more tombstones anyway. These thresholds may also be adjusted at runtime +using the StorageService mbean. + +*Default Value:* 1000 + +``tombstone_failure_threshold`` +------------------------------- + +*Default Value:* 100000 + +``batch_size_warn_threshold_in_kb`` +----------------------------------- + +Log WARN on any batch size exceeding this value. 5kb per batch by default. +Caution should be taken on increasing the size of this threshold as it can lead to node instability. + +*Default Value:* 5 + +``batch_size_fail_threshold_in_kb`` +----------------------------------- + +Fail any batch exceeding this value. 50kb (10x warn threshold) by default. + +*Default Value:* 50 + +``unlogged_batch_across_partitions_warn_threshold`` +--------------------------------------------------- + +Log WARN on any batches not of type LOGGED than span across more partitions than this limit + +*Default Value:* 10 + +``compaction_large_partition_warning_threshold_mb`` +--------------------------------------------------- + +Log a warning when compacting partitions larger than this value + +*Default Value:* 100 + +``gc_warn_threshold_in_ms`` +--------------------------- + +GC Pauses greater than gc_warn_threshold_in_ms will be logged at WARN level +Adjust the threshold based on your application throughput requirement +By default, Cassandra logs GC Pauses greater than 200 ms at INFO level + +*Default Value:* 1000 + +``max_value_size_in_mb`` +------------------------ +*This option is commented out by default.* + +Maximum size of any value in SSTables. Safety measure to detect SSTable corruption +early. Any value size larger than this threshold will result into marking an SSTable +as corrupted. + +*Default Value:* 256 diff --git a/doc/source/configuration/index.rst b/doc/source/configuration/index.rst new file mode 100644 index 0000000000..f774fdad67 --- /dev/null +++ b/doc/source/configuration/index.rst @@ -0,0 +1,25 @@ +.. Licensed to the Apache Software Foundation (ASF) under one +.. or more contributor license agreements. See the NOTICE file +.. distributed with this work for additional information +.. regarding copyright ownership. The ASF licenses this file +.. to you under the Apache License, Version 2.0 (the +.. "License"); you may not use this file except in compliance +.. with the License. You may obtain a copy of the License at +.. +.. http://www.apache.org/licenses/LICENSE-2.0 +.. +.. Unless required by applicable law or agreed to in writing, software +.. distributed under the License is distributed on an "AS IS" BASIS, +.. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +.. See the License for the specific language governing permissions and +.. limitations under the License. + +Configuring Cassandra +===================== + +This section describes how to configure Apache Cassandra. + +.. toctree:: + :maxdepth: 1 + + cassandra_config_file diff --git a/doc/source/cql.rst b/doc/source/cql.rst deleted file mode 100644 index 8d185a2ee6..0000000000 --- a/doc/source/cql.rst +++ /dev/null @@ -1,4114 +0,0 @@ -.. Licensed to the Apache Software Foundation (ASF) under one -.. or more contributor license agreements. See the NOTICE file -.. distributed with this work for additional information -.. regarding copyright ownership. The ASF licenses this file -.. to you under the Apache License, Version 2.0 (the -.. "License"); you may not use this file except in compliance -.. with the License. You may obtain a copy of the License at -.. -.. http://www.apache.org/licenses/LICENSE-2.0 -.. -.. Unless required by applicable law or agreed to in writing, software -.. distributed under the License is distributed on an "AS IS" BASIS, -.. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -.. See the License for the specific language governing permissions and -.. limitations under the License. - -.. highlight:: sql - -.. _UUID: https://en.wikipedia.org/wiki/Universally_unique_identifier - -The Cassandra Query Language (CQL) -================================== - -This document describes the Cassandra Query Language (CQL) [#]_. Note that this document describes the last version of -the languages. However, the `changes <#changes>`_ section provides the diff between the different versions of CQL. - -CQL offers a model close to SQL in the sense that data is put in *tables* containing *rows* of *columns*. For -that reason, when used in this document, these terms (tables, rows and columns) have the same definition than they have -in SQL. But please note that as such, they do **not** refer to the concept of rows and columns found in the deprecated -thrift API (and earlier version 1 and 2 of CQL). - -.. _definitions: - -Definitions ------------ - -.. _conventions: - -Conventions -^^^^^^^^^^^ - -To aid in specifying the CQL syntax, we will use the following conventions in this document: - -- Language rules will be given in an informal `BNF variant - `_ notation. In particular, we'll use square brakets - (``[ item ]``) for optional items, ``*`` and ``+`` for repeated items (where ``+`` imply at least one). -- The grammar will also use the following convention for convenience: non-terminal term will be lowercase (and link to - their definition) while terminal keywords will be provided "all caps". Note however that keywords are - :ref:`identifiers` and are thus case insensitive in practice. We will also define some early construction using - regexp, which we'll indicate with ``re()``. -- The grammar is provided for documentation purposes and leave some minor details out. For instance, the comma on the - last column definition in a ``CREATE TABLE`` statement is optional but supported if present even though the grammar in - this document suggests otherwise. Also, not everything accepted by the grammar is necessarily valid CQL. -- References to keywords or pieces of CQL code in running text will be shown in a ``fixed-width font``. - - -.. _identifiers: - -Identifiers and keywords -^^^^^^^^^^^^^^^^^^^^^^^^ - -The CQL language uses *identifiers* (or *names*) to identify tables, columns and other objects. An identifier is a token -matching the regular expression ``[a-zA-Z][a-zA-Z0-9_]*``. - -A number of such identifiers, like ``SELECT`` or ``WITH``, are *keywords*. They have a fixed meaning for the language -and most are reserved. The list of those keywords can be found in :ref:`appendix-A`. - -Identifiers and (unquoted) keywords are case insensitive. Thus ``SELECT`` is the same than ``select`` or ``sElEcT``, and -``myId`` is the same than ``myid`` or ``MYID``. A convention often used (in particular by the samples of this -documentation) is to use upper case for keywords and lower case for other identifiers. - -There is a second kind of identifiers called *quoted identifiers* defined by enclosing an arbitrary sequence of -characters (non empty) in double-quotes(``"``). Quoted identifiers are never keywords. Thus ``"select"`` is not a -reserved keyword and can be used to refer to a column (note that using this is particularly advised), while ``select`` -would raise a parsing error. Also, contrarily to unquoted identifiers and keywords, quoted identifiers are case -sensitive (``"My Quoted Id"`` is *different* from ``"my quoted id"``). A fully lowercase quoted identifier that matches -``[a-zA-Z][a-zA-Z0-9_]*`` is however *equivalent* to the unquoted identifier obtained by removing the double-quote (so -``"myid"`` is equivalent to ``myid`` and to ``myId`` but different from ``"myId"``). Inside a quoted identifier, the -double-quote character can be repeated to escape it, so ``"foo "" bar"`` is a valid identifier. - -.. note:: *quoted identifiers* allows to declare columns with arbitrary names, and those can sometime clash with - specific names used by the server. For instance, when using conditional update, the server will respond with a - result-set containing a special result named ``"[applied]"``. If you’ve declared a column with such a name, this - could potentially confuse some tools and should be avoided. In general, unquoted identifiers should be preferred but - if you use quoted identifiers, it is strongly advised to avoid any name enclosed by squared brackets (like - ``"[applied]"``) and any name that looks like a function call (like ``"f(x)"``). - -More formally, we have: - -.. productionlist:: - identifier: `unquoted_identifier` | `quoted_identifier` - unquoted_identifier: re('[a-zA-Z][a-zA-Z0-9_]*') - quoted_identifier: '"' (any character where " can appear if doubled)+ '"' - -.. _constants: - -Constants -^^^^^^^^^ - -CQL defines the following kind of *constants*: - -.. productionlist:: - constant: `string` | `integer` | `float` | `boolean` | `uuid` | `blob` | NULL - string: '\'' (any character where ' can appear if doubled)+ '\'' - : '$$' (any character other than '$$') '$$' - integer: re('-?[0-9]+') - float: re('-?[0-9]+(\.[0-9]*)?([eE][+-]?[0-9+])?') | NAN | INFINITY - boolean: TRUE | FALSE - uuid: `hex`{8}-`hex`{4}-`hex`{4}-`hex`{4}-`hex`{12} - hex: re("[0-9a-fA-F]") - blob: '0' ('x' | 'X') `hex`+ - -In other words: - -- A string constant is an arbitrary sequence of characters enclosed by single-quote(``'``). A single-quote - can be included by repeating it, e.g. ``'It''s raining today'``. Those are not to be confused with quoted - :ref:`identifiers` that use double-quotes. Alternatively, a string can be defined by enclosing the arbitrary sequence - of characters by two dollar characters, in which case single-quote can be use without escaping (``$$It's raining - today$$``). That latter form is often used when defining :ref:`user-defined functions ` to avoid having to - escape single-quote characters in function body (as they are more likely to occur than ``$$``). -- Integer, float and boolean constant are defined as expected. Note however than float allows the special ``NaN`` and - ``Infinity`` constants. -- CQL supports UUID_ constants. -- Blobs content are provided in hexadecimal and prefixed by ``0x``. -- The special ``NULL`` constant denotes the absence of value. - -For how these constants are typed, see the :ref:`data-types` section. - -Terms -^^^^^ - -CQL has the notion of a *term*, which denotes the kind of values that CQL support. Terms are defined by: - -.. productionlist:: - term: `constant` | `literal` | `function_call` | `type_hint` | `bind_marker` - literal: `collection_literal` | `udt_literal` | `tuple_literal` - function_call: `identifier` '(' [ `term` (',' `term`)* ] ')' - type_hint: '(' `cql_type` `)` term - bind_marker: '?' | ':' `identifier` - -A term is thus one of: - -- A :ref:`constant `. -- A literal for either :ref:`a collection `, :ref:`a user-defined type ` or :ref:`a tuple ` - (see the linked sections for details). -- A function call: see :ref:`the section on functions ` for details on which :ref:`native function - ` exists and how to define your own :ref:`user-defined ones `. -- A *type hint*: see the :ref:`related section ` for details. -- A bind marker, which denotes a variable to be bound at execution time. See the section on :ref:`prepared-statements` - for details. A bind marker can be either anonymous (``?``) or named (``:some_name``). The latter form provides a more - convenient way to refer to the variable for binding it and should generally be preferred. - - -Comments -^^^^^^^^ - -A comment in CQL is a line beginning by either double dashes (``--``) or double slash (``//``). - -Multi-line comments are also supported through enclosure within ``/*`` and ``*/`` (but nesting is not supported). - -:: - - — This is a comment - // This is a comment too - /* This is - a multi-line comment */ - -Statements -^^^^^^^^^^ - -CQL consists of statements that can be divided in the following categories: - -- :ref:`data-definition` statements, to define and change how the data is stored (keyspaces and tables). -- :ref:`data-manipulation` statements, for selecting, inserting and deleting data. -- :ref:`index-and-views` statements. -- :ref:`roles-and-permissions` statements. -- :ref:`udfs` statements. -- :ref:`udts` statements. -- :ref:`triggers` statements. - -All the statements are listed below and are described in the rest of this documentation (see links above): - -.. productionlist:: - cql_statement: `statement` [ ';' ] - statement: `ddl_statement` - : | `dml_statement` - : | `index_or_view_statement` - : | `role_or_permission_statement` - : | `udf_statement` - : | `udt_statement` - : | `trigger_statement` - ddl_statement: `use_statement` - : | `create_keyspace_statement` - : | `alter_keyspace_statement` - : | `drop_keyspace_statement` - : | `create_table_statement` - : | `alter_table_statement` - : | `drop_table_statement` - : | `truncate_statement` - dml_statement: `select_statement` - : | `insert_statement` - : | `update_statement` - : | `delete_statement` - : | `batch_statement` - index_or_view_statement: `create_index_statement` - : | `drop_index_statement` - : | `create_materialized_view_statement` - : | `drop_materialized_view_statement` - role_or_permission_statement: `create_role_statement` - : | `alter_role_statement` - : | `drop_role_statement` - : | `grant_role_statement` - : | `revoke_role_statement` - : | `list_role_statement` - : | `grant_permission_statement` - : | `revoke_permission_statement` - : | `list_permission_statement` - : | `create_user_statement` - : | `alter_user_statement` - : | `drop_user_statement` - : | `list_user_statement` - udf_statement: `create_function_statement` - : | `drop_function_statement` - : | `create_aggregate_statement` - : | `drop_aggregate_statement` - udt_statement: `create_type_statement` - : | `alter_type_statement` - : | `drop_type_statement` - trigger_statement: `create_trigger_statement` - : | `drop_trigger_statement` - -.. _prepared-statements: - -Prepared Statements -^^^^^^^^^^^^^^^^^^^ - -CQL supports *prepared statements*. Prepared statements are an optimization that allows to parse a query only once but -execute it multiple times with different concrete values. - -Any statement that uses at least one bind marker (see :token:`bind_marker`) will need to be *prepared*. After which the statement -can be *executed* by provided concrete values for each of its marker. The exact details of how a statement is prepared -and then executed depends on the CQL driver used and you should refer to your driver documentation. - - -.. _data-types: - -Data Types ----------- - -CQL is a typed language and supports a rich set of data types, including :ref:`native types `, -:ref:`collection types `, :ref:`user-defined types `, :ref:`tuple types ` and :ref:`custom -types `: - -.. productionlist:: - cql_type: `native_type` | `collection_type` | `user_defined_type` | `tuple_type` | `custom_type` - - -.. _native-types: - -Native Types -^^^^^^^^^^^^ - -The native types supported by CQL are: - -.. productionlist:: - native_type: ASCII - : | BIGINT - : | BLOB - : | BOOLEAN - : | COUNTER - : | DATE - : | DECIMAL - : | DOUBLE - : | FLOAT - : | INET - : | INT - : | SMALLINT - : | TEXT - : | TIME - : | TIMESTAMP - : | TIMEUUID - : | TINYINT - : | UUID - : | VARCHAR - : | VARINT - -The following table gives additional informations on the native data types, and on which kind of :ref:`constants -` each type supports: - -=============== ===================== ================================================================================== - type constants supported description -=============== ===================== ================================================================================== - ``ascii`` :token:`string` ASCII character string - ``bigint`` :token:`integer` 64-bit signed long - ``blob`` :token:`blob` Arbitrary bytes (no validation) - ``boolean`` :token:`boolean` Either ``true`` or ``false`` - ``counter`` :token:`integer` Counter column (64-bit signed value). See :ref:`counters` for details - ``date`` :token:`integer`, A date (with no corresponding time value). See :ref:`dates` below for details - :token:`string` - ``decimal`` :token:`integer`, Variable-precision decimal - :token:`float` - ``double`` :token:`integer` 64-bit IEEE-754 floating point - :token:`float` - ``float`` :token:`integer`, 32-bit IEEE-754 floating point - :token:`float` - ``inet`` :token:`string` An IP address, either IPv4 (4 bytes long) or IPv6 (16 bytes long). Note that - there is no ``inet`` constant, IP address should be input as strings - ``int`` :token:`integer` 32-bit signed int - ``smallint`` :token:`integer` 16-bit signed int - ``text`` :token:`string` UTF8 encoded string - ``time`` :token:`integer`, A time (with no corresponding date value) with nanosecond precision. See - :token:`string` :ref:`times` below for details - ``timestamp`` :token:`integer`, A timestamp (date and time) with millisecond precision. See :ref:`timestamps` - :token:`string` below for details - ``timeuuid`` :token:`uuid` Version 1 UUID_, generally used as a “conflict-free” timestamp. Also see - :ref:`timeuuid-functions` - ``tinyint`` :token:`integer` 8-bit signed int - ``uuid`` :token:`uuid` A UUID_ (of any version) - ``varchar`` :token:`string` UTF8 encoded string - ``varint`` :token:`integer` Arbitrary-precision integer -=============== ===================== ================================================================================== - -.. _counters: - -Counters -~~~~~~~~ - -The ``counter`` type is used to define *counter columns*. A counter column is a column whose value is a 64-bit signed -integer and on which 2 operations are supported: incrementing and decrementing (see the :ref:`UPDATE statement -` for syntax). Note that the value of a counter cannot be set: a counter does not exist until first -incremented/decremented, and that first increment/decrement is made as if the prior value was 0. - -.. _counter-limitations: - -Counters have a number of important limitations: - -- They cannot be used for columns part of the ``PRIMARY KEY`` of a table. -- A table that contains a counter can only contain counters. In other words, either all the columns of a table outside - the ``PRIMARY KEY`` have the ``counter`` type, or none of them have it. -- Counters do not support :ref:`expiration `. -- The deletion of counters is supported, but is only guaranteed to work the first time you delete a counter. In other - words, you should not re-update a counter that you have deleted (if you do, proper behavior is not guaranteed). -- Counter updates are, by nature, not `idemptotent `__. An important - consequence is that if a counter update fails unexpectedly (timeout or loss of connection to the coordinator node), - the client has no way to know if the update has been applied or not. In particular, replaying the update may or may - not lead to an over count. - -.. _timestamps: - -Working with timestamps -^^^^^^^^^^^^^^^^^^^^^^^ - -Values of the ``timestamp`` type are encoded as 64-bit signed integers representing a number of milliseconds since the -standard base time known as `the epoch `__: January 1 1970 at 00:00:00 GMT. - -Timestamps can be input in CQL either using their value as an :token:`integer`, or using a :token:`string` that -represents an `ISO 8601 `__ date. For instance, all of the values below are -valid ``timestamp`` values for Mar 2, 2011, at 04:05:00 AM, GMT: - -- ``1299038700000`` -- ``'2011-02-03 04:05+0000'`` -- ``'2011-02-03 04:05:00+0000'`` -- ``'2011-02-03 04:05:00.000+0000'`` -- ``'2011-02-03T04:05+0000'`` -- ``'2011-02-03T04:05:00+0000'`` -- ``'2011-02-03T04:05:00.000+0000'`` - -The ``+0000`` above is an RFC 822 4-digit time zone specification; ``+0000`` refers to GMT. US Pacific Standard Time is -``-0800``. The time zone may be omitted if desired (``'2011-02-03 04:05:00'``), and if so, the date will be interpreted -as being in the time zone under which the coordinating Cassandra node is configured. There are however difficulties -inherent in relying on the time zone configuration being as expected, so it is recommended that the time zone always be -specified for timestamps when feasible. - -The time of day may also be omitted (``'2011-02-03'`` or ``'2011-02-03+0000'``), in which case the time of day will -default to 00:00:00 in the specified or default time zone. However, if only the date part is relevant, consider using -the :ref:`date ` type. - -.. _dates: - -Working with dates -^^^^^^^^^^^^^^^^^^ - -Values of the ``date`` type are encoded as 32-bit unsigned integers representing a number of days with “the epoch” at -the center of the range (2^31). Epoch is January 1st, 1970 - -As for :ref:`timestamp `, a date can be input either as an :token:`integer` or using a date -:token:`string`. In the later case, the format should be ``yyyy-mm-dd`` (so ``'2011-02-03'`` for instance). - -.. _times: - -Working with times -^^^^^^^^^^^^^^^^^^ - -Values of the ``time`` type are encoded as 64-bit signed integers representing the number of nanoseconds since midnight. - -As for :ref:`timestamp `, a time can be input either as an :token:`integer` or using a :token:`string` -representing the time. In the later case, the format should be ``hh:mm:ss[.fffffffff]`` (where the sub-second precision -is optional and if provided, can be less than the nanosecond). So for instance, the following are valid inputs for a -time: - -- ``'08:12:54'`` -- ``'08:12:54.123'`` -- ``'08:12:54.123456'`` -- ``'08:12:54.123456789'`` - - -.. _collections: - -Collections -^^^^^^^^^^^ - -CQL supports 3 kind of collections: :ref:`maps`, :ref:`sets` and :ref:`lists`. The types of those collections is defined -by: - -.. productionlist:: - collection_type: MAP '<' `cql_type` ',' `cql_type` '>' - : | SET '<' `cql_type` '>' - : | LIST '<' `cql_type` '>' - -and their values can be inputd using collection literals: - -.. productionlist:: - collection_literal: `map_literal` | `set_literal` | `list_literal` - map_literal: '{' [ `term` ':' `term` (',' `term` : `term`)* ] '}' - set_literal: '{' [ `term` (',' `term`)* ] '}' - list_literal: '[' [ `term` (',' `term`)* ] ']' - -Note however that neither :token:`bind_marker` nor ``NULL`` are supported inside collection literals. - -Noteworthy characteristics -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Collections are meant for storing/denormalizing relatively small amount of data. They work well for things like “the -phone numbers of a given user”, “labels applied to an email”, etc. But when items are expected to grow unbounded (“all -messages sent by a user”, “events registered by a sensor”...), then collections are not appropriate and a specific table -(with clustering columns) should be used. Concretely, (non-frozen) collections have the following noteworthy -characteristics and limitations: - -- Individual collections are not indexed internally. Which means that even to access a single element of a collection, - the while collection has to be read (and reading one is not paged internally). -- While insertion operations on sets and maps never incur a read-before-write internally, some operations on lists do. - Further, some lists operations are not idempotent by nature (see the section on :ref:`lists ` below for - details), making their retry in case of timeout problematic. It is thus advised to prefer sets over lists when - possible. - -Please note that while some of those limitations may or may not be removed/improved upon in the future, it is a -anti-pattern to use a (single) collection to store large amounts of data. - -.. _maps: - -Maps -~~~~ - -A ``map`` is a (sorted) set of key-value pairs, where keys are unique and the map is sorted by its keys. You can define -and insert a map with:: - - CREATE TABLE users ( - id text PRIMARY KEY, - name text, - favs map // A map of text keys, and text values - ); - - INSERT INTO users (id, name, favs) - VALUES ('jsmith', 'John Smith', { 'fruit' : 'Apple', 'band' : 'Beatles' }); - - // Replace the existing map entirely. - UPDATE users SET favs = { 'fruit' : 'Banana' } WHERE id = 'jsmith'; - -Further, maps support: - -- Updating or inserting one or more elements:: - - UPDATE users SET favs['author'] = 'Ed Poe' WHERE id = 'jsmith'; - UPDATE users SET favs = favs + { 'movie' : 'Cassablanca', 'band' : 'ZZ Top' } WHERE id = 'jsmith'; - -- Removing one or more element (if an element doesn't exist, removing it is a no-op but no error is thrown):: - - DELETE favs['author'] FROM users WHERE id = 'jsmith'; - UPDATE users SET favs = favs - { 'movie', 'band'} WHERE id = 'jsmith'; - - Note that for removing multiple elements in a ``map``, you remove from it a ``set`` of keys. - -Lastly, TTLs are allowed for both ``INSERT`` and ``UPDATE``, but in both case the TTL set only apply to the newly -inserted/updated elements. In other words:: - - UPDATE users USING TTL 10 SET favs['color'] = 'green' WHERE id = 'jsmith'; - -will only apply the TTL to the ``{ 'color' : 'green' }`` record, the rest of the map remaining unaffected. - - -.. _sets: - -Sets -~~~~ - -A ``set`` is a (sorted) collection of unique values. You can define and insert a map with:: - - CREATE TABLE images ( - name text PRIMARY KEY, - owner text, - tags set // A set of text values - ); - - INSERT INTO images (name, owner, tags) - VALUES ('cat.jpg', 'jsmith', { 'pet', 'cute' }); - - // Replace the existing set entirely - UPDATE images SET tags = { 'kitten', 'cat’, 'lol' } WHERE id = 'jsmith'; - -Further, sets support: - -- Adding one or multiple elements (as this is a set, inserting an already existing element is a no-op):: - - UPDATE images SET tags = tags + { 'gray', 'cuddly' } WHERE name = 'cat.jpg'; - -- Removing one or multiple elements (if an element doesn't exist, removing it is a no-op but no error is thrown):: - - UPDATE images SET tags = tags - { 'cat' } WHERE name = 'cat.jpg'; - -Lastly, as for :ref:`maps `, TTLs if used only apply to the newly inserted values. - -.. _lists: - -Lists -~~~~~ - -.. note:: As mentioned above and further discussed at the end of this section, lists have limitations and specific - performance considerations that you should take into account before using them. In general, if you can use a - :ref:`set ` instead of list, always prefer a set. - -A ``list`` is a (sorted) collection of non-unique values where elements are ordered by there position in the list. You -can define and insert a list with:: - - CREATE TABLE plays ( - id text PRIMARY KEY, - game text, - players int, - scores list // A list of integers - ) - - INSERT INTO plays (id, game, players, scores) - VALUES ('123-afde', 'quake', 3, [17, 4, 2]); - - // Replace the existing list entirely - UPDATE plays SET scores = [ 3, 9, 4] WHERE id = '123-afde'; - -Further, lists support: - -- Appending and prepending values to a list:: - - UPDATE plays SET players = 5, scores = scores + [ 14, 21 ] WHERE id = '123-afde'; - UPDATE plays SET players = 6, scores = [ 3 ] + scores WHERE id = '123-afde'; - -- Setting the value at a particular position in the list. This imply that the list has a pre-existing element for that - position or an error will be thrown that the list is too small:: - - UPDATE plays SET scores[1] = 7 WHERE id = '123-afde'; - -- Removing an element by its position in the list. This imply that the list has a pre-existing element for that position - or an error will be thrown that the list is too small. Further, as the operation removes an element from the list, the - list size will be diminished by 1, shifting the position of all the elements following the one deleted:: - - DELETE scores[1] FROM plays WHERE id = '123-afde'; - -- Deleting *all* the occurrences of particular values in the list (if a particular element doesn't occur at all in the - list, it is simply ignored and no error is thrown):: - - UPDATE plays SET scores = scores - [ 12, 21 ] WHERE id = '123-afde'; - -.. warning:: The append and prepend operations are not idempotent by nature. So in particular, if one of these operation - timeout, then retrying the operation is not safe and it may (or may not) lead to appending/prepending the value - twice. - -.. warning:: Setting and removing an element by position and removing occurences of particular values incur an internal - *read-before-write*. They will thus run more slowly and take more ressources than usual updates (with the exclusion - of conditional write that have their own cost). - -Lastly, as for :ref:`maps `, TTLs when used only apply to the newly inserted values. - -.. _udts: - -User-Defined Types -^^^^^^^^^^^^^^^^^^ - -CQL support the definition of user-defined types (UDT for short). Such a type can be created, modified and removed using -the :token:`create_type_statement`, :token:`alter_type_statement` and :token:`drop_type_statement` described below. But -once created, a UDT is simply referred to by its name: - -.. productionlist:: - user_defined_type: `udt_name` - udt_name: [ `keyspace_name` '.' ] `identifier` - - -Creating a UDT -~~~~~~~~~~~~~~ - -Creating a new user-defined type is done using a ``CREATE TYPE`` statement defined by: - -.. productionlist:: - create_type_statement: CREATE TYPE [ IF NOT EXISTS ] `udt_name` - : '(' `field_definition` ( ',' `field_definition` )* ')' - field_definition: `identifier` `cql_type` - -A UDT has a name (used to declared columns of that type) and is a set of named and typed fields. Fields name can be any -type, including collections or other UDT. For instance:: - - CREATE TYPE phone ( - country_code int, - number text, - ) - - CREATE TYPE address ( - street text, - city text, - zip int, - phones map - ) - - CREATE TABLE user ( - name text PRIMARY KEY, - addresses map> - ) - -Note that: - -- Attempting to create an already existing type will result in an error unless the ``IF NOT EXISTS`` option is used. If - it is used, the statement will be a no-op if the type already exists. -- A type is intrinsically bound to the keyspace in which it is created, and can only be used in that keyspace. At - creation, if the type name is prefixed by a keyspace name, it is created in that keyspace. Otherwise, it is created in - the current keyspace. -- As of Cassandra |version|, UDT have to be frozen in most cases, hence the ``frozen
`` in the table definition - above. Please see the section on :ref:`frozen ` for more details. - -UDT literals -~~~~~~~~~~~~ - -Once a used-defined type has been created, value can be input using a UDT literal: - -.. productionlist:: - udt_literal: '{' `identifier` ':' `term` ( ',' `identifier` ':' `term` )* '}' - -In other words, a UDT literal is like a :ref:`map ` literal but its keys are the names of the fields of the type. -For instance, one could insert into the table define in the previous section using:: - - INSERT INTO user (name, addresses) - VALUES ('z3 Pr3z1den7', { - 'home' : { - street: '1600 Pennsylvania Ave NW', - city: 'Washington', - zip: '20500', - phones: { 'cell' : { country_code: 1, number: '202 456-1111' }, - 'landline' : { country_code: 1, number: '...' } } - } - 'work' : { - street: '1600 Pennsylvania Ave NW', - city: 'Washington', - zip: '20500', - phones: { 'fax' : { country_code: 1, number: '...' } } - } - }) - -To be valid, a UDT literal should only include fields defined by the type it is a literal of, but it can omit some field -(in which case those will be ``null``). - -Altering a UDT -~~~~~~~~~~~~~~ - -An existing user-defined type can be modified using an ``ALTER TYPE`` statement: - -.. productionlist:: - alter_type_statement: ALTER TYPE `udt_name` `alter_type_modification` - alter_type_modification: ALTER `identifier` TYPE `cql_type` - : | ADD `field_definition` - : | RENAME `identifier` TO `identifier` ( `identifier` TO `identifier` )* - -You can: - -- modify the type of particular field (``ALTER TYPE address ALTER zip TYPE bigint``). The restrictions for such change - are the same than when :ref:`altering the type of column `. -- add a new field to the type (``ALTER TYPE address ADD country text``). That new field will be ``null`` for any values - of the type created before the addition. -- rename the fields of the type (``ALTER TYPE address RENAME zip TO zipcode``). - -Dropping a UDT -~~~~~~~~~~~~~~ - -You can drop an existing user-defined type using a ``DROP TYPE`` statement: - -.. productionlist:: - drop_type_statement: DROP TYPE [ IF EXISTS ] `udt_name` - -Dropping a type results in the immediate, irreversible removal of that type. However, attempting to drop a type that is -still in use by another type, table or function will result in an error. - -If the type dropped does not exist, an error will be returned unless ``IF EXISTS`` is used, in which case the operation -is a no-op. - -.. _tuples: - -Tuples -^^^^^^ - -CQL also support tuples and tuple types (where the elements can be of different types). Functionally, tuples can be -though as anonymous UDT with anonymous fields. Tuple types and tuple literals are defined by: - -.. productionlist:: - tuple_type: TUPLE '<' `cql_type` ( ',' `cql_type` )* '>' - tuple_literal: '(' `term` ( ',' `term` )* ')' - -and can be used thusly:: - - CREATE TABLE durations ( - event text, - duration tuple, - ) - - INSERT INTO durations (event, duration) VALUES ('ev1', (3, 'hours')); - -Unlike other "composed" types (collections and UDT), a tuple is always :ref:`frozen ` (without the need of the -`frozen` keyword) and it is not possible to update only some elements of a tuple (without updating the whole tuple). -Also, a tuple literal should always have the same number of value than declared in the type it is a tuple of (some of -those values can be null but they need to be explicitly declared as so). - -.. _custom-types: - -Custom Types -^^^^^^^^^^^^ - -.. note:: Custom types exists mostly for backward compatiliby purposes and their usage is discouraged. Their usage is - complex, not user friendly and the other provided types, particularly :ref:`user-defined types `, should almost - always be enough. - -A custom type is defined by: - -.. productionlist:: - custom_type: `string` - -A custom type is a :token:`string` that contains the name of Java class that extends the server side ``AbstractType`` -class and that can be loaded by Cassandra (it should thus be in the ``CLASSPATH`` of every node running Cassandra). That -class will define what values are valid for the type and how the time sorts when used for a clustering column. For any -other purpose, a value of a custom type is the same than that of a ``blob``, and can in particular be input using the -:token:`blob` literal syntax. - - -.. _data-definition: - -Data Definition ---------------- - -CQL stores data in *tables*, whose schema defines the layout of said data in the table, and those tables are grouped in -*keyspaces*. A keyspace defines a number of options that applies to all the tables it contains, most prominently of -which is the :ref:`replication strategy ` used by the keyspace. It is generally encouraged to use -one keyspace by *application*, and thus many cluster may define only one keyspace. - -This section describes the statements used to create, modify, and remove those keyspace and tables. - -Common definitions -^^^^^^^^^^^^^^^^^^ - -The names of the keyspaces and tables are defined by the following grammar: - -.. productionlist:: - keyspace_name: `name` - table_name: [ `keyspace_name` '.' ] `name` - name: `unquoted_name` | `quoted_name` - unquoted_name: re('[a-zA-Z_0-9]{1, 48}') - quoted_name: '"' `unquoted_name` '"' - -Both keyspace and table name should be comprised of only alphanumeric characters, cannot be empty and are limited in -size to 48 characters (that limit exists mostly to avoid filenames (which may include the keyspace and table name) to go -over the limits of certain file systems). By default, keyspace and table names are case insensitive (``myTable`` is -equivalent to ``mytable``) but case sensitivity can be forced by using double-quotes (``"myTable"`` is different from -``mytable``). - -Further, a table is always part of a keyspace and a table name can be provided fully-qualified by the keyspace it is -part of. If is is not fully-qualified, the table is assumed to be in the *current* keyspace (see :ref:`USE statement -`). - -We also define the notion of statement options for use in the following section: - -.. productionlist:: - options: `option` ( AND `option` )* - option: `identifier` '=' ( `identifier` | `constant` | `map_literal` ) - -.. _create-keyspace-statement: - -CREATE KEYSPACE -^^^^^^^^^^^^^^^ - -A keyspace is created using a ``CREATE KEYSPACE`` statement: - -.. productionlist:: - create_keyspace_statement: CREATE KEYSPACE [ IF NOT EXISTS ] `keyspace_name` WITH `options` - -For instance:: - - CREATE KEYSPACE Excelsior - WITH replication = {'class': 'SimpleStrategy', 'replication_factor' : 3}; - - CREATE KEYSPACE Excalibur - WITH replication = {'class': 'NetworkTopologyStrategy', 'DC1' : 1, 'DC2' : 3} - AND durable_writes = false; - - -.. _create-keyspace-options: -The supported ``options`` are: - -=================== ========== =========== ========= =================================================================== -name kind mandatory default description -=================== ========== =========== ========= =================================================================== -``replication`` *map* yes The replication strategy and options to use for the keyspace (see - details below). -``durable_writes`` *simple* no true Whether to use the commit log for updates on this keyspace - (disable this option at your own risk!). -=================== ========== =========== ========= =================================================================== - -The ``replication`` property is mandatory and must at least contains the ``'class'`` sub-option which defines the -:ref:`replication strategy ` class to use. The rest of the sub-options depends on what replication -strategy is used. By default, Cassandra support the following ``'class'``: - -- ``'SimpleStrategy'``: A simple strategy that defines a replication factor for the whole cluster. The only sub-options - supported is ``'replication_factor'`` to define that replication factor and is mandatory. -- ``'NetworkTopologyStrategy'``: A replication strategy that allows to set the replication factor independently for - each data-center. The rest of the sub-options are key-value pairs where a key is a data-center name and its value is - the associated replication factor. - -Attempting to create a keyspace that already exists will return an error unless the ``IF NOT EXISTS`` option is used. If -it is used, the statement will be a no-op if the keyspace already exists. - -.. _use-statement: - -USE -^^^ - -The ``USE`` statement allows to change the *current* keyspace (for the *connection* on which it is executed). A number -of objects in CQL are bound to a keyspace (tables, user-defined types, functions, ...) and the current keyspace is the -default keyspace used when those objects are referred without a fully-qualified name (that is, without being prefixed a -keyspace name). A ``USE`` statement simply takes the keyspace to use as current as argument: - -.. productionlist:: - use_statement: USE `keyspace_name` - -.. _alter-keyspace-statement: - -ALTER KEYSPACE -^^^^^^^^^^^^^^ - -An ``ALTER KEYSPACE`` statement allows to modify the options of a keyspace: - -.. productionlist:: - alter_keyspace_statement: ALTER KEYSPACE `keyspace_name` WITH `options` - -For instance:: - - ALTER KEYSPACE Excelsior - WITH replication = {’class’: ‘SimpleStrategy’, ‘replication_factor’ : 4}; - -The supported options are the same than for :ref:`creating a keyspace `. - -.. _drop-keyspace-statement: - -DROP KEYSPACE -^^^^^^^^^^^^^ - -Dropping a keyspace can be done using the ``DROP KEYSPACE`` statement: - -.. productionlist:: - drop_keyspace_statement: DROP KEYSPACE [ IF EXISTS ] `keyspace_name` - -For instance:: - - DROP KEYSPACE Excelsior; - -Dropping a keyspace results in the immediate, irreversible removal of that keyspace, including all the tables, UTD and -functions in it, and all the data contained in those tables. - -If the keyspace does not exists, the statement will return an error, unless ``IF EXISTS`` is used in which case the -operation is a no-op. - -.. _create-table-statement: - -CREATE TABLE -^^^^^^^^^^^^ - -Creating a new table uses the ``CREATE TABLE`` statement: - -.. productionlist:: - create_table_statement: CREATE TABLE [ IF NOT EXISTS ] `table_name` - : '(' - : `column_definition` - : ( ',' `column_definition` )* - : [ ',' PRIMARY KEY '(' `primary_key` ')' ] - : ')' [ WITH `table_options` ] - column_definition: `identifier` `cql_type` [ STATIC ] [ PRIMARY KEY] - primary_key: `partition_key` [ ',' `clustering_columns` ] - partition_key: `identifier` - : | '(' `identifier` ( ',' `identifier` )* ')' - clustering_columns: `identifier` ( ',' `identifier` )* - table_options: COMPACT STORAGE [ AND `table_options` ] - : | CLUSTERING ORDER BY '(' `clustering_order` ')' [ AND `table_options` ] - : | `options` - clustering_order: `identifier` (ASC | DESC) ( ',' `identifier` (ASC | DESC) )* - -For instance:: - - CREATE TABLE monkeySpecies ( - species text PRIMARY KEY, - common_name text, - population varint, - average_size int - ) WITH comment=‘Important biological records’ - AND read_repair_chance = 1.0; - - CREATE TABLE timeline ( - userid uuid, - posted_month int, - posted_time uuid, - body text, - posted_by text, - PRIMARY KEY (userid, posted_month, posted_time) - ) WITH compaction = { ‘class’ : ‘LeveledCompactionStrategy’ }; - - CREATE TABLE loads ( - machine inet, - cpu int, - mtime timeuuid, - load float, - PRIMARY KEY ((machine, cpu), mtime) - ) WITH CLUSTERING ORDER BY (mtime DESC); - -A CQL table has a name and is composed of a set of *rows*. Creating a table amounts to defining which :ref:`columns -` the rows will be composed, which of those columns compose the :ref:`primary key `, as -well as optional :ref:`options ` for the table. - -Attempting to create an already existing table will return an error unless the ``IF NOT EXISTS`` directive is used. If -it is used, the statement will be a no-op if the table already exists. - - -.. _column-definition: - -Column definitions -~~~~~~~~~~~~~~~~~~ - -Every rows in a CQL table has a set of predefined columns defined at the time of the table creation (or added later -using an :ref:`alter statement`). - -A :token:`column_definition` is primarily comprised of the name of the column defined and it's :ref:`type `, -which restrict which values are accepted for that column. Additionally, a column definition can have the following -modifiers: - -``STATIC`` - it declares the column as being a :ref:`static column `. - -``PRIMARY KEY`` - it declares the column as being the sole component of the :ref:`primary key ` of the table. - -.. _static-columns: - -Static columns -`````````````` -Some columns can be declared as ``STATIC`` in a table definition. A column that is static will be “shared” by all the -rows belonging to the same partition (having the same :ref:`partition key `). For instance:: - - CREATE TABLE t ( - pk int, - t int, - v text, - s text static, - PRIMARY KEY (pk, t) - ); - - INSERT INTO t (pk, t, v, s) VALUES (0, 0, 'val0', 'static0'); - INSERT INTO t (pk, t, v, s) VALUES (0, 1, 'val1', 'static1'); - - SELECT * FROM t; - pk | t | v | s - ----+---+--------+----------- - 0 | 0 | 'val0' | 'static1' - 0 | 1 | 'val1' | 'static1' - -As can be seen, the ``s`` value is the same (``static1``) for both of the row in the partition (the partition key in -that example being ``pk``, both rows are in that same partition): the 2nd insertion has overridden the value for ``s``. - -The use of static columns as the following restrictions: - -- tables with the ``COMPACT STORAGE`` option (see below) cannot use them. -- a table without clustering columns cannot have static columns (in a table without clustering columns, every partition - has only one row, and so every column is inherently static). -- only non ``PRIMARY KEY`` columns can be static. - -.. _primary-key: - -The Primary key -~~~~~~~~~~~~~~~ - -Within a table, a row is uniquely identified by its ``PRIMARY KEY``, and hence all table **must** define a PRIMARY KEY -(and only one). A ``PRIMARY KEY`` definition is composed of one or more of the columns defined in the table. -Syntactically, the primary key is defined the keywords ``PRIMARY KEY`` followed by comma-separated list of the column -names composing it within parenthesis, but if the primary key has only one column, one can alternatively follow that -column definition by the ``PRIMARY KEY`` keywords. The order of the columns in the primary key definition matter. - -A CQL primary key is composed of 2 parts: - -- the :ref:`partition key ` part. It is the first component of the primary key definition. It can be a - single column or, using additional parenthesis, can be multiple columns. A table always have at least a partition key, - the smallest possible table definition is:: - - CREATE TABLE t (k text PRIMARY KEY); - -- the :ref:`clustering columns `. Those are the columns after the first component of the primary key - definition, and the order of those columns define the *clustering order*. - -Some example of primary key definition are: - -- ``PRIMARY KEY (a)``: ``a`` is the partition key and there is no clustering columns. -- ``PRIMARY KEY (a, b, c)`` : ``a`` is the partition key and ``b`` and ``c`` are the clustering columns. -- ``PRIMARY KEY ((a, b), c)`` : ``a`` and ``b`` compose the partition key (this is often called a *composite* partition - key) and ``c`` is the clustering column. - - -.. _partition-key: - -The partition key -````````````````` - -Within a table, CQL defines the notion of a *partition*. A partition is simply the set of rows that share the same value -for their partition key. Note that if the partition key is composed of multiple columns, then rows belong to the same -partition only they have the same values for all those partition key column. So for instance, given the following table -definition and content:: - - CREATE TABLE t ( - a int, - b int, - c int, - d int, - PRIMARY KEY ((a, b), c, d) - ); - - SELECT * FROM t; - a | b | c | d - ---+---+---+--- - 0 | 0 | 0 | 0 // row 1 - 0 | 0 | 1 | 1 // row 2 - 0 | 1 | 2 | 2 // row 3 - 0 | 1 | 3 | 3 // row 4 - 1 | 1 | 4 | 4 // row 5 - -``row 1`` and ``row 2`` are in the same partition, ``row 3`` and ``row 4`` are also in the same partition (but a -different one) and ``row 5`` is in yet another partition. - -Note that a table always has a partition key, and that if the table has no :ref:`clustering columns -`, then every partition of that table is only comprised of a single row (since the primary key -uniquely identifies rows and the primary key is equal to the partition key if there is no clustering columns). - -The most important property of partition is that all the rows belonging to the same partition are guarantee to be stored -on the same set of replica nodes. In other words, the partition key of a table defines which of the rows will be -localized together in the Cluster, and it is thus important to choose your partition key wisely so that rows that needs -to be fetch together are in the same partition (so that querying those rows together require contacting a minimum of -nodes). - -Please note however that there is a flip-side to this guarantee: as all rows sharing a partition key are guaranteed to -be stored on the same set of replica node, a partition key that groups too much data can create a hotspot. - -Another useful property of a partition is that when writing data, all the updates belonging to a single partition are -done *atomically* and in *isolation*, which is not the case across partitions. - -The proper choice of the partition key and clustering columns for a table is probably one of the most important aspect -of data modeling in Cassandra, and it largely impact which queries can be performed, and how efficiently they are. - - -.. _clustering-columns: - -The clustering columns -`````````````````````` - -The clustering columns of a table defines the clustering order for the partition of that table. For a given -:ref:`partition `, all the rows are physically ordered inside Cassandra by that clustering order. For -instance, given:: - - CREATE TABLE t ( - a int, - b int, - c int, - PRIMARY KEY (a, c, d) - ); - - SELECT * FROM t; - a | b | c - ---+---+--- - 0 | 0 | 4 // row 1 - 0 | 1 | 9 // row 2 - 0 | 2 | 2 // row 3 - 0 | 3 | 3 // row 4 - -then the rows (which all belong to the same partition) are all stored internally in the order of the values of their -``b`` column (the order they are displayed above). So where the partition key of the table allows to group rows on the -same replica set, the clustering columns controls how those rows are stored on the replica. That sorting allows the -retrieval of a range of rows within a partition (for instance, in the example above, ``SELECT * FROM t WHERE a = 0 AND b -> 1 and b <= 3``) very efficient. - - -.. _create-table-options - -Table options -~~~~~~~~~~~~~ - -A CQL table has a number of options that can be set at creation (and, for most of them, :ref:`altered -` later). These options are specified after the ``WITH`` keyword. - -Amongst those options, two important ones cannot be changed after creation and influence which queries can be done -against the table: the ``COMPACT STORAGE`` option and the ``CLUSTERING ORDER`` option. Those, as well as the other -options of a table are described in the following sections. - -.. _compact-storage: - -Compact tables -`````````````` - -.. warning:: Since Cassandra 3.0, compact tables have the exact same layout internally than non compact ones (for the - same schema obviously), and declaring a table compact **only** creates artificial limitations on the table definition - and usage that are necessary to ensure backward compatibility with the deprecated Thrift API. And as ``COMPACT - STORAGE`` cannot, as of Cassandra |3.8|, be removed, it is strongly discouraged to create new table with the - ``COMPACT STORAGE`` option. - -A *compact* table is one defined with the ``COMPACT STORAGE`` option. This option is mainly targeted towards backward -compatibility for definitions created before CQL version 3 (see `www.datastax.com/dev/blog/thrift-to-cql3 -`__ for more details) and shouldn't be used for new tables. Declaring a -table with this option creates limitations for the table which are largely arbitrary but necessary for backward -compatibility with the (deprecated) Thrift API. Amongst those limitation: - -- a compact table cannot use collections nor static columns. -- if a compact table has at least one clustering column, then it must have *exactly* one column outside of the primary - key ones. This imply you cannot add or remove columns after creation in particular. -- a compact table is limited in the indexes it can create, and no materialized view can be created on it. - -.. _clustering-order: - -Reversing the clustering order -`````````````````````````````` - -The clustering order of a table is defined by the :ref:`clustering columns ` of that table. By -default, that ordering is based on natural order of those clustering order, but the ``CLUSTERING ORDER`` allows to -change that clustering order to use the *reverse* natural order for some (potentially all) of the columns. - -The ``CLUSTERING ORDER`` option takes the comma-separated list of the clustering column, each with a ``ASC`` (for -*ascendant*, e.g. the natural order) or ``DESC`` (for *descendant*, e.g. the reverse natural order). Note in particular -that the default (if the ``CLUSTERING ORDER`` option is not used) is strictly equivalent to using the option with all -clustering columns using the ``ASC`` modifier. - -Note that this option is basically a hint for the storage engine to change the order in which it stores the row but it -has 3 visible consequences: - -# it limits which ``ORDER BY`` clause are allowed for :ref:`selects ` on that table. You can only - order results by the clustering order or the reverse clustering order. Meaning that if a table has 2 clustering column - ``a`` and ``b`` and you defined ``WITH CLUSTERING ORDER (a DESC, b ASC)``, then in queries you will be allowed to use - ``ORDER BY (a DESC, b ASC)`` and (reverse clustering order) ``ORDER BY (a ASC, b DESC)`` but **not** ``ORDER BY (a - ASC, b ASC)`` (nor ``ORDER BY (a DESC, b DESC)``). -# it also change the default order of results when queried (if no ``ORDER BY`` is provided). Results are always returned - in clustering order (within a partition). -# it has a small performance impact on some queries as queries in reverse clustering order are slower than the one in - forward clustering order. In practice, this means that if you plan on querying mostly in the reverse natural order of - your columns (which is common with time series for instance where you often want data from the newest to the oldest), - it is an optimization to declare a descending clustering order. - -.. _create-table-general-options: - -Other table options -``````````````````` - -.. todo:: review (misses cdc if nothing else) and link to proper categories when appropriate (compaction for instance) - -A table supports the following options: - -+----------------------------------+------------+---------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| option | kind | default | description | -+==================================+============+===============+=================================================================================================================================================================================================================================+ -| ``comment`` | *simple* | none | A free-form, human-readable comment. | -+----------------------------------+------------+---------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``read_repair_chance`` | *simple* | 0.1 | The probability with which to query extra nodes (e.g. more nodes than required by the consistency level) for the purpose of read repairs. | -+----------------------------------+------------+---------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``dclocal_read_repair_chance`` | *simple* | 0 | The probability with which to query extra nodes (e.g. more nodes than required by the consistency level) belonging to the same data center than the read coordinator for the purpose of read repairs. | -+----------------------------------+------------+---------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``gc_grace_seconds`` | *simple* | 864000 | Time to wait before garbage collecting tombstones (deletion markers). | -+----------------------------------+------------+---------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``bloom_filter_fp_chance`` | *simple* | 0.00075 | The target probability of false positive of the sstable bloom filters. Said bloom filters will be sized to provide the provided probability (thus lowering this value impact the size of bloom filters in-memory and on-disk) | -+----------------------------------+------------+---------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``default_time_to_live`` | *simple* | 0 | The default expiration time (“TTL”) in seconds for a table. | -+----------------------------------+------------+---------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``compaction`` | *map* | *see below* | Compaction options, see “below”:#compactionOptions. | -+----------------------------------+------------+---------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``compression`` | *map* | *see below* | Compression options, see “below”:#compressionOptions. | -+----------------------------------+------------+---------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``caching`` | *map* | *see below* | Caching options, see “below”:#cachingOptions. | -+----------------------------------+------------+---------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -Compaction options -################## - -The ``compaction`` property must at least define the ``'class'`` -sub-option, that defines the compaction strategy class to use. The -default supported class are ``'SizeTieredCompactionStrategy'``, -``'LeveledCompactionStrategy'``, ``'DateTieredCompactionStrategy'`` and -``'TimeWindowCompactionStrategy'``. Custom strategy can be provided by -specifying the full class name as a `string constant <#constants>`__. -The rest of the sub-options depends on the chosen class. The sub-options -supported by the default classes are: - -+--------------------------------------+---------------------------------+----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| option | supported compaction strategy | default | description | -+======================================+=================================+================+========================================================================================================================================================================================================================================================================================================================================+ -| ``enabled`` | *all* | true | A boolean denoting whether compaction should be enabled or not. | -+--------------------------------------+---------------------------------+----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``tombstone_threshold`` | *all* | 0.2 | A ratio such that if a sstable has more than this ratio of gcable tombstones over all contained columns, the sstable will be compacted (with no other sstables) for the purpose of purging those tombstones. | -+--------------------------------------+---------------------------------+----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``tombstone_compaction_interval`` | *all* | 1 day | The minimum time to wait after an sstable creation time before considering it for “tombstone compaction”, where “tombstone compaction” is the compaction triggered if the sstable has more gcable tombstones than ``tombstone_threshold``. | -+--------------------------------------+---------------------------------+----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``unchecked_tombstone_compaction`` | *all* | false | Setting this to true enables more aggressive tombstone compactions - single sstable tombstone compactions will run without checking how likely it is that they will be successful. | -+--------------------------------------+---------------------------------+----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``min_sstable_size`` | SizeTieredCompactionStrategy | 50MB | The size tiered strategy groups SSTables to compact in buckets. A bucket groups SSTables that differs from less than 50% in size. However, for small sizes, this would result in a bucketing that is too fine grained. ``min_sstable_size`` defines a size threshold (in bytes) below which all SSTables belong to one unique bucket | -+--------------------------------------+---------------------------------+----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``min_threshold`` | SizeTieredCompactionStrategy | 4 | Minimum number of SSTables needed to start a minor compaction. | -+--------------------------------------+---------------------------------+----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``max_threshold`` | SizeTieredCompactionStrategy | 32 | Maximum number of SSTables processed by one minor compaction. | -+--------------------------------------+---------------------------------+----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``bucket_low`` | SizeTieredCompactionStrategy | 0.5 | Size tiered consider sstables to be within the same bucket if their size is within [average\_size \* ``bucket_low``, average\_size \* ``bucket_high`` ] (i.e the default groups sstable whose sizes diverges by at most 50%) | -+--------------------------------------+---------------------------------+----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``bucket_high`` | SizeTieredCompactionStrategy | 1.5 | Size tiered consider sstables to be within the same bucket if their size is within [average\_size \* ``bucket_low``, average\_size \* ``bucket_high`` ] (i.e the default groups sstable whose sizes diverges by at most 50%). | -+--------------------------------------+---------------------------------+----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``sstable_size_in_mb`` | LeveledCompactionStrategy | 5MB | The target size (in MB) for sstables in the leveled strategy. Note that while sstable sizes should stay less or equal to ``sstable_size_in_mb``, it is possible to exceptionally have a larger sstable as during compaction, data for a given partition key are never split into 2 sstables | -+--------------------------------------+---------------------------------+----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``timestamp_resolution`` | DateTieredCompactionStrategy | MICROSECONDS | The timestamp resolution used when inserting data, could be MILLISECONDS, MICROSECONDS etc (should be understandable by Java TimeUnit) - don’t change this unless you do mutations with USING TIMESTAMP (or equivalent directly in the client) | -+--------------------------------------+---------------------------------+----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``base_time_seconds`` | DateTieredCompactionStrategy | 60 | The base size of the time windows. | -+--------------------------------------+---------------------------------+----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``max_sstable_age_days`` | DateTieredCompactionStrategy | 365 | SSTables only containing data that is older than this will never be compacted. | -+--------------------------------------+---------------------------------+----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``timestamp_resolution`` | TimeWindowCompactionStrategy | MICROSECONDS | The timestamp resolution used when inserting data, could be MILLISECONDS, MICROSECONDS etc (should be understandable by Java TimeUnit) - don’t change this unless you do mutations with USING TIMESTAMP (or equivalent directly in the client) | -+--------------------------------------+---------------------------------+----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``compaction_window_unit`` | TimeWindowCompactionStrategy | DAYS | The Java TimeUnit used for the window size, set in conjunction with ``compaction_window_size``. Must be one of DAYS, HOURS, MINUTES | -+--------------------------------------+---------------------------------+----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``compaction_window_size`` | TimeWindowCompactionStrategy | 1 | The number of ``compaction_window_unit`` units that make up a time window. | -+--------------------------------------+---------------------------------+----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -Compression options -################### - -For the ``compression`` property, the following sub-options are -available: - -+------------------------+-----------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| option | default | description | -+========================+=================+=======================================================================================================================================================================================================================================================================================================================================================================================================================+ -| ``class`` | LZ4Compressor | The compression algorithm to use. Default compressor are: LZ4Compressor, SnappyCompressor and DeflateCompressor. Use ``'enabled' : false`` to disable compression. Custom compressor can be provided by specifying the full class name as a “string constant”:#constants. | -+------------------------+-----------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``enabled`` | true | By default compression is enabled. To disable it, set ``enabled`` to ``false`` | -+------------------------+-----------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|`` chunk_length_in_kb`` | 64KB | On disk SSTables are compressed by block (to allow random reads). This defines the size (in KB) of said block. Bigger values may improve the compression rate, but increases the minimum size of data to be read from disk for a read | -+------------------------+-----------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``crc_check_chance`` | 1.0 | When compression is enabled, each compressed block includes a checksum of that block for the purpose of detecting disk bitrot and avoiding the propagation of corruption to other replica. This option defines the probability with which those checksums are checked during read. By default they are always checked. Set to 0 to disable checksum checking and to 0.5 for instance to check them every other read | -+------------------------+-----------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -Caching options -############### - -For the ``caching`` property, the following sub-options are available: - -+--------------------------+-----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| option | default | description | -+==========================+===========+============================================================================================================================================================================================================================================================================+ -| ``keys`` | ALL | Whether to cache keys (“key cache”) for this table. Valid values are: ``ALL`` and ``NONE``. | -+--------------------------+-----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``rows_per_partition`` | NONE | The amount of rows to cache per partition (“row cache”). If an integer ``n`` is specified, the first ``n`` queried rows of a partition will be cached. Other possible options are ``ALL``, to cache all rows of a queried partition, or ``NONE`` to disable row caching. | -+--------------------------+-----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -Other considerations: -##################### - -- When `inserting <#insertStmt>`__ / `updating <#updateStmt>`__ a given - row, not all columns needs to be defined (except for those part of - the key), and missing columns occupy no space on disk. Furthermore, - adding new columns (see \ ``ALTER TABLE``\ ) is a constant time - operation. There is thus no need to try to anticipate future usage - (or to cry when you haven’t) when creating a table. - -ALTER TABLE -^^^^^^^^^^^ - -Altering an existing table uses the ``ALTER TABLE`` statement: - -.. productionlist:: - alter_table_statement: ALTER TABLE `table_name` `alter_table_instruction` - alter_table_instruction: ALTER `identifier` TYPE `cql_type` - : | ADD `identifier` `cql_type` ( ',' `identifier` `cql_type` )* - : | DROP `identifier` ( `identifier` )* - : | WITH `options` - -For instance:: - - ALTER TABLE addamsFamily ALTER lastKnownLocation TYPE uuid; - - ALTER TABLE addamsFamily ADD gravesite varchar; - - ALTER TABLE addamsFamily - WITH comment = ‘A most excellent and useful table’ - AND read_repair_chance = 0.2; - -The ``ALTER TABLE`` statement can: - -- Change the type of one of the column in the table (through the ``ALTER`` instruction). Note that the type of a column - cannot be changed arbitrarily. The change of type should be such that any value of the previous type should be a valid - value of the new type. Further, for :ref:`clustering columns ` and columns on which a secondary - index is defined, the new type must sort values in the same way the previous type does. See the :ref:`type - compatibility table ` below for detail on which type changes are accepted. -- Add new column(s) to the table (through the ``ADD`` instruction). Note that the primary key of a table cannot be - changed and thus newly added column will, by extension, never be part of the primary key. Also note that :ref:`compact - tables ` have restrictions regarding column addition. -- Remove column(s) from the table. This drops both the column and all its content, but note that while the column - becomes immediately unavailable, its content is only removed lazily during compaction. Please also see the warnings - below. -- Change some of the table options (through the ``WITH`` instruction). The :ref:`supported options - ` are the same that when creating a table (outside of ``COMPACT STORAGE`` and ``CLUSTERING - ORDER`` that cannot be changed after creation). Note that setting any ``compaction`` sub-options has the effect of - erasing all previous ``compaction`` options, so you need to re-specify all the sub-options if you want to keep them. - The same note applies to the set of ``compression`` sub-options. - -.. warning:: Dropping a column assumes that the timestamps used for the value of this column are "real" timestamp in - microseconds. Using "real" timestamps in microseconds is the default is and is **strongly** recommended but as - Cassandra allows the client to provide any timestamp on any table it is theoretically possible to use another - convention. Please be aware that if you do so, dropping a column will not work correctly. - -.. warning:: Once a column is dropped, it is allowed to re-add a column with the same name than the dropped one - **unless* the type of the dropped column was a (non-frozen) column (due to an internal technical limitation). - -.. _alter-table-type-compatibility: - -CQL type compatibility: -~~~~~~~~~~~~~~~~~~~~~~~ - -CQL data types may be converted only as the following table. - -+-------------------------------------------------------+--------------------+ -| Existing type | Can be altered to: | -+=======================================================+====================+ -| timestamp | bigint | -+-------------------------------------------------------+--------------------+ -| ascii, bigint, boolean, date, decimal, double, float, | blob | -| inet, int, smallint, text, time, timestamp, timeuuid, | | -| tinyint, uuid, varchar, varint | | -+-------------------------------------------------------+--------------------+ -| int | date | -+-------------------------------------------------------+--------------------+ -| ascii, varchar | text | -+-------------------------------------------------------+--------------------+ -| bigint | time | -+-------------------------------------------------------+--------------------+ -| bigint | timestamp | -+-------------------------------------------------------+--------------------+ -| timeuuid | uuid | -+-------------------------------------------------------+--------------------+ -| ascii, text | varchar | -+-------------------------------------------------------+--------------------+ -| bigint, int, timestamp | varint | -+-------------------------------------------------------+--------------------+ - -Clustering columns have stricter requirements, only the following conversions are allowed: - -+------------------------+-------------------+ -| Existing type | Can be altered to | -+========================+===================+ -| ascii, text, varchar | blob | -+------------------------+-------------------+ -| ascii, varchar | text | -+------------------------+-------------------+ -| ascii, text | varchar | -+------------------------+-------------------+ - -DROP TABLE -^^^^^^^^^^ - -*Syntax:* - -bc(syntax). ::= DROP TABLE ( IF EXISTS )? - -*Sample:* - -bc(sample). DROP TABLE worldSeriesAttendees; - -The ``DROP TABLE`` statement results in the immediate, irreversible -removal of a table, including all data contained in it. As for table -creation, ``DROP COLUMNFAMILY`` is allowed as an alias for -``DROP TABLE``. - -If the table does not exist, the statement will return an error, unless -``IF EXISTS`` is used in which case the operation is a no-op. - -TRUNCATE -^^^^^^^^ - -*Syntax:* - -bc(syntax). ::= TRUNCATE ( TABLE \| COLUMNFAMILY )? - -*Sample:* - -bc(sample). TRUNCATE superImportantData; - -The ``TRUNCATE`` statement permanently removes all data from a table. - - -.. _data-manipulation: - -Data Manipulation ------------------ - -SELECT -^^^^^^ - -*Syntax:* - -| bc(syntax).. -| ::= SELECT ( JSON )? -| FROM -| ( WHERE )? -| ( ORDER BY )? -| ( PER PARTITION LIMIT )? -| ( LIMIT )? -| ( ALLOW FILTERING )? - -| ::= DISTINCT? -| \| COUNT ‘(’ ( ‘\*’ \| ‘1’ ) ‘)’ (AS )? - -| ::= (AS )? ( ‘,’ (AS )? )\* -| \| ‘\*’ - -| ::= -| \| WRITETIME ‘(’ ‘)’ -| \| TTL ‘(’ ‘)’ -| \| CAST ‘(’ AS ‘)’ -| \| ‘(’ ( (‘,’ )\*)? ‘)’ - - ::= ( AND )\* - -| ::= -| \| ‘(’ (‘,’ )\* ‘)’ -| \| IN ‘(’ ( ( ‘,’ )\* )? ‘)’ -| \| ‘(’ (‘,’ )\* ‘)’ IN ‘(’ ( ( ‘,’ )\* )? ‘)’ -| \| TOKEN ‘(’ ( ‘,’ )\* ‘)’ - -| ::= ‘=’ \| ‘<’ \| ‘>’ \| ‘<=’ \| ‘>=’ \| CONTAINS \| CONTAINS KEY -| ::= ( ‘,’ )\* -| ::= ( ASC \| DESC )? -| ::= ‘(’ (‘,’ )\* ‘)’ -| p. -| *Sample:* - -| bc(sample).. -| SELECT name, occupation FROM users WHERE userid IN (199, 200, 207); - -SELECT JSON name, occupation FROM users WHERE userid = 199; - -SELECT name AS user\_name, occupation AS user\_occupation FROM users; - -| SELECT time, value -| FROM events -| WHERE event\_type = ‘myEvent’ -| AND time > ‘2011-02-03’ -| AND time <= ‘2012-01-01’ - -SELECT COUNT (\*) FROM users; - -SELECT COUNT (\*) AS user\_count FROM users; - -The ``SELECT`` statements reads one or more columns for one or more rows -in a table. It returns a result-set of rows, where each row contains the -collection of columns corresponding to the query. If the ``JSON`` -keyword is used, the results for each row will contain only a single -column named “json”. See the section on -```SELECT JSON`` <#selectJson>`__ for more details. - -```` -~~~~~~~~~~~~~~~~~~~ - -The ```` determines which columns needs to be queried and -returned in the result-set. It consists of either the comma-separated -list of or the wildcard character (``*``) to select all the columns -defined for the table. - -A ```` is either a column name to retrieve or a ```` -of one or more ````\ s. The function allowed are the same as for -```` and are described in the `function section <#functions>`__. -In addition to these generic functions, the ``WRITETIME`` (resp. -``TTL``) function allows to select the timestamp of when the column was -inserted (resp. the time to live (in seconds) for the column (or null if -the column has no expiration set)) and the ```CAST`` <#castFun>`__ -function can be used to convert one data type to another. - -Any ```` can be aliased using ``AS`` keyword (see examples). -Please note that ```` and ```` clause should -refer to the columns by their original names and not by their aliases. - -The ``COUNT`` keyword can be used with parenthesis enclosing ``*``. If -so, the query will return a single result: the number of rows matching -the query. Note that ``COUNT(1)`` is supported as an alias. - -```` -~~~~~~~~~~~~~~~~~~ - -The ```` specifies which rows must be queried. It is -composed of relations on the columns that are part of the -``PRIMARY KEY`` and/or have a `secondary index <#createIndexStmt>`__ -defined on them. - -Not all relations are allowed in a query. For instance, non-equal -relations (where ``IN`` is considered as an equal relation) on a -partition key are not supported (but see the use of the ``TOKEN`` method -below to do non-equal queries on the partition key). Moreover, for a -given partition key, the clustering columns induce an ordering of rows -and relations on them is restricted to the relations that allow to -select a **contiguous** (for the ordering) set of rows. For instance, -given - -| bc(sample). -| CREATE TABLE posts ( -| userid text, -| blog\_title text, -| posted\_at timestamp, -| entry\_title text, -| content text, -| category int, -| PRIMARY KEY (userid, blog\_title, posted\_at) -| ) - -The following query is allowed: - -| bc(sample). -| SELECT entry\_title, content FROM posts WHERE userid=‘john doe’ AND - blog\_title=‘John’‘s Blog’ AND posted\_at >= ‘2012-01-01’ AND - posted\_at < ‘2012-01-31’ - -But the following one is not, as it does not select a contiguous set of -rows (and we suppose no secondary indexes are set): - -| bc(sample). -| // Needs a blog\_title to be set to select ranges of posted\_at -| SELECT entry\_title, content FROM posts WHERE userid=‘john doe’ AND - posted\_at >= ‘2012-01-01’ AND posted\_at < ‘2012-01-31’ - -When specifying relations, the ``TOKEN`` function can be used on the -``PARTITION KEY`` column to query. In that case, rows will be selected -based on the token of their ``PARTITION_KEY`` rather than on the value. -Note that the token of a key depends on the partitioner in use, and that -in particular the RandomPartitioner won’t yield a meaningful order. Also -note that ordering partitioners always order token values by bytes (so -even if the partition key is of type int, ``token(-1) > token(0)`` in -particular). Example: - -| bc(sample). -| SELECT \* FROM posts WHERE token(userid) > token(‘tom’) AND - token(userid) < token(‘bob’) - -Moreover, the ``IN`` relation is only allowed on the last column of the -partition key and on the last column of the full primary key. - -It is also possible to “group” ``CLUSTERING COLUMNS`` together in a -relation using the tuple notation. For instance: - -| bc(sample). -| SELECT \* FROM posts WHERE userid=‘john doe’ AND (blog\_title, - posted\_at) > (‘John’‘s Blog’, ‘2012-01-01’) - -will request all rows that sorts after the one having “John’s Blog” as -``blog_tile`` and ‘2012-01-01’ for ``posted_at`` in the clustering -order. In particular, rows having a ``post_at <= '2012-01-01'`` will be -returned as long as their ``blog_title > 'John''s Blog'``, which -wouldn’t be the case for: - -| bc(sample). -| SELECT \* FROM posts WHERE userid=‘john doe’ AND blog\_title > - ‘John’‘s Blog’ AND posted\_at > ‘2012-01-01’ - -The tuple notation may also be used for ``IN`` clauses on -``CLUSTERING COLUMNS``: - -| bc(sample). -| SELECT \* FROM posts WHERE userid=‘john doe’ AND (blog\_title, - posted\_at) IN ((‘John’‘s Blog’, ‘2012-01-01), (’Extreme Chess’, - ‘2014-06-01’)) - -The ``CONTAINS`` operator may only be used on collection columns (lists, -sets, and maps). In the case of maps, ``CONTAINS`` applies to the map -values. The ``CONTAINS KEY`` operator may only be used on map columns -and applies to the map keys. - -```` -~~~~~~~~~~~~~~ - -The ``ORDER BY`` option allows to select the order of the returned -results. It takes as argument a list of column names along with the -order for the column (``ASC`` for ascendant and ``DESC`` for descendant, -omitting the order being equivalent to ``ASC``). Currently the possible -orderings are limited (which depends on the table -```CLUSTERING ORDER`` <#createTableOptions>`__ ): - -- if the table has been defined without any specific - ``CLUSTERING ORDER``, then then allowed orderings are the order - induced by the clustering columns and the reverse of that one. -- otherwise, the orderings allowed are the order of the - ``CLUSTERING ORDER`` option and the reversed one. - -``LIMIT`` and ``PER PARTITION LIMIT`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The ``LIMIT`` option to a ``SELECT`` statement limits the number of rows -returned by a query, while the ``PER PARTITION LIMIT`` option limits the -number of rows returned for a given partition by the query. Note that -both type of limit can used in the same statement. - -``ALLOW FILTERING`` -~~~~~~~~~~~~~~~~~~~ - -By default, CQL only allows select queries that don’t involve -“filtering” server side, i.e. queries where we know that all (live) -record read will be returned (maybe partly) in the result set. The -reasoning is that those “non filtering” queries have predictable -performance in the sense that they will execute in a time that is -proportional to the amount of data **returned** by the query (which can -be controlled through ``LIMIT``). - -The ``ALLOW FILTERING`` option allows to explicitly allow (some) queries -that require filtering. Please note that a query using -``ALLOW FILTERING`` may thus have unpredictable performance (for the -definition above), i.e. even a query that selects a handful of records -**may** exhibit performance that depends on the total amount of data -stored in the cluster. - -For instance, considering the following table holding user profiles with -their year of birth (with a secondary index on it) and country of -residence: - -| bc(sample).. -| CREATE TABLE users ( -| username text PRIMARY KEY, -| firstname text, -| lastname text, -| birth\_year int, -| country text -| ) - -| CREATE INDEX ON users(birth\_year); -| p. - -Then the following queries are valid: - -| bc(sample). -| SELECT \* FROM users; -| SELECT firstname, lastname FROM users WHERE birth\_year = 1981; - -because in both case, Cassandra guarantees that these queries -performance will be proportional to the amount of data returned. In -particular, if no users are born in 1981, then the second query -performance will not depend of the number of user profile stored in the -database (not directly at least: due to secondary index implementation -consideration, this query may still depend on the number of node in the -cluster, which indirectly depends on the amount of data stored. -Nevertheless, the number of nodes will always be multiple number of -magnitude lower than the number of user profile stored). Of course, both -query may return very large result set in practice, but the amount of -data returned can always be controlled by adding a ``LIMIT``. - -However, the following query will be rejected: - -| bc(sample). -| SELECT firstname, lastname FROM users WHERE birth\_year = 1981 AND - country = ‘FR’; - -because Cassandra cannot guarantee that it won’t have to scan large -amount of data even if the result to those query is small. Typically, it -will scan all the index entries for users born in 1981 even if only a -handful are actually from France. However, if you “know what you are -doing”, you can force the execution of this query by using -``ALLOW FILTERING`` and so the following query is valid: - -| bc(sample). -| SELECT firstname, lastname FROM users WHERE birth\_year = 1981 AND - country = ‘FR’ ALLOW FILTERING; - -INSERT -^^^^^^ - -*Syntax:* - -| bc(syntax).. -| ::= INSERT INTO -| ( ( VALUES ) -| \| ( JSON )) -| ( IF NOT EXISTS )? -| ( USING ( AND )\* )? - - ::= ‘(’ ( ‘,’ )\* ‘)’ - - ::= ‘(’ ( ‘,’ )\* ‘)’ - -| ::= -| \| - -| ::= TIMESTAMP -| \| TTL -| p. -| *Sample:* - -| bc(sample).. -| INSERT INTO NerdMovies (movie, director, main\_actor, year) -| VALUES (‘Serenity’, ‘Joss Whedon’, ‘Nathan Fillion’, 2005) -| USING TTL 86400; - -| INSERT INTO NerdMovies JSON ‘{`movie <>`__ “Serenity”, `director <>`__ - “Joss Whedon”, `year <>`__ 2005}’ -| p. -| The ``INSERT`` statement writes one or more columns for a given row in - a table. Note that since a row is identified by its ``PRIMARY KEY``, - at least the columns composing it must be specified. The list of - columns to insert to must be supplied when using the ``VALUES`` - syntax. When using the ``JSON`` syntax, they are optional. See the - section on ```INSERT JSON`` <#insertJson>`__ for more details. - -Note that unlike in SQL, ``INSERT`` does not check the prior existence -of the row by default: the row is created if none existed before, and -updated otherwise. Furthermore, there is no mean to know which of -creation or update happened. - -It is however possible to use the ``IF NOT EXISTS`` condition to only -insert if the row does not exist prior to the insertion. But please note -that using ``IF NOT EXISTS`` will incur a non negligible performance -cost (internally, Paxos will be used) so this should be used sparingly. - -All updates for an ``INSERT`` are applied atomically and in isolation. - -Please refer to the ```UPDATE`` <#updateOptions>`__ section for -information on the ``