How to Install Apache Cassandra on Rocky Linux 10

how to install Apache Cassandra on Rocky Linux 10

Apache Cassandra is a distributed wide-column NoSQL database built for massive write throughput, linear horizontal scaling and no single point of failure. It powers workloads such as messaging, IoT telemetry, user activity feeds and recommendation stores. This guide installs Apache Cassandra 5.0 on Rocky Linux 10 using the official Apache RPM repository, tunes the operating system, secures the node, opens the right firewall ports, handles SELinux, and then shows how to grow the node into a 3-node cluster.

Table of Contents

  1. Cassandra in 60 Seconds
  2. Choosing a Cassandra Version
  3. Lab Architecture
  4. Prerequisites
  5. Step 1: Update the System and Set the Hostname
  6. Step 2: Install Java
  7. Step 3: Tune Linux for Cassandra
  8. Step 4: Add the Apache Cassandra Repository
  9. Step 5: Install Cassandra
  10. Step 6: Configure cassandra.yaml
  11. Step 7: Start Cassandra and Verify
  12. Step 8: Firewall and SELinux
  13. Step 9: Enable Authentication
  14. Step 10: First Keyspace, Table and Query
  15. Expanding to a 3-Node Cluster
  16. Backup and Maintenance
  17. Useful Files and Commands
  18. Troubleshooting
  19. FAQ
  20. Conclusion

1. Cassandra in 60 Seconds

Cassandra has no primary node. Every node is equal, data is spread across the cluster by a hash of the partition key, and each row is stored on several nodes according to the replication factor. You choose, per query, how many replicas must respond (the consistency level), which lets you trade consistency against latency and availability.

SQL conceptCassandra equivalentNote
Database / schemaKeyspaceHolds replication settings
TableTableDesigned around your queries, not around entities
Primary keyPartition key + clustering columnsPartition key decides where data lives; clustering columns decide sort order within it
JOINNot supportedDenormalize data instead
TransactionsLimited (lightweight transactions)Not a general ACID engine
ScalingAdd nodesRoughly linear, no downtime

Cassandra rewards query-first data modelling. If your workload needs joins, ad-hoc analytics and strong multi-row transactions, a relational database is a better fit.

2. Choosing a Cassandra Version

AspectCassandra 4.1Cassandra 5.0
Java support8 and 1111 and 17
Key new featuresImproved configuration and guardrailsStorage-Attached Indexes (SAI), vector data type and vector search, Unified Compaction Strategy, trie-based memtables and SSTables, new CQL functions
RPM repository path41x50x
Recommended forExisting clusters that are not yet upgradingNew installations

This guide uses the 5.0 line with OpenJDK 17. If Apache has released a newer stable line by the time you read this, check the download page and adjust the repository path and Java version accordingly.

3. Lab Architecture

                       Rocky Linux 10 host(s)
   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
   โ”‚  Client / App โ”€โ”€โ–บ :9042 (CQL native transport)                 โ”‚
   โ”‚                       โ”‚                                        โ”‚
   โ”‚            โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                            โ”‚
   โ”‚            โ”‚  Apache Cassandra 5.0โ”‚  JVM: OpenJDK 17           โ”‚
   โ”‚            โ”‚  โ”œโ”€ commitlog        โ”‚  /var/lib/cassandra/commitlog
   โ”‚            โ”‚  โ”œโ”€ data (SSTables)  โ”‚  /var/lib/cassandra/data   โ”‚
   โ”‚            โ”‚  โ””โ”€ gossip :7000     โ”‚โ—„โ”€โ”€โ–บ other nodes (:7000)    โ”‚
   โ”‚            โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                            โ”‚
   โ”‚  JMX :7199 (localhost only) โ—„โ”€โ”€ nodetool                       โ”‚
   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

   3-node target:   node1 (seed) โ—„โ”€โ”€โ–บ node2 (seed) โ—„โ”€โ”€โ–บ node3
                          same cluster_name, same datacenter, RF = 3

4. Prerequisites

RequirementRecommendation
OSRocky Linux 10 (fresh install)
CPU4 vCPU minimum for a lab; 8 or more for production. Rocky Linux 10 expects a modern x86-64 CPU baseline (x86-64-v3), so very old CPUs and some VM CPU models may not be supported
RAM8 GB minimum for a lab; 16 to 32 GB or more for production nodes
DiskSSD or NVMe on XFS; put the commit log on a separate device in production
NetworkStatic IP, working DNS or /etc/hosts entries, and NTP time sync
AccessA user with sudo privileges

5. Step 1: Update the System and Set the Hostname

sudo dnf -y update
sudo dnf -y install chrony curl wget vim tar

sudo hostnamectl set-hostname cass01.example.local
sudo systemctl enable --now chronyd
chronyc tracking

Cassandra depends on synchronized clocks because it uses timestamps to resolve conflicting writes. Confirm chrony reports a small offset before continuing.

6. Step 2: Install Java

sudo dnf -y install java-17-openjdk-headless
java -version

If several Java versions are installed, select the right one:

sudo alternatives --config java

7. Step 3: Tune Linux for Cassandra

These settings avoid the most common production problems.

Disable swap

sudo swapoff -a
sudo sed -i '/\sswap\s/ s/^/#/' /etc/fstab
free -h

Kernel parameters

sudo tee /etc/sysctl.d/99-cassandra.conf > /dev/null <<'EOF'
vm.max_map_count = 1048575
vm.swappiness = 1
net.ipv4.tcp_keepalive_time = 60
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.tcp_keepalive_intvl = 10
EOF
sudo sysctl --system

Resource limits

The Cassandra RPM normally installs /etc/security/limits.d/cassandra.conf. Check it after installation (Step 5) and make sure it contains at least:

cassandra - memlock unlimited
cassandra - nofile  100000
cassandra - nproc   32768
cassandra - as      unlimited

Transparent Huge Pages

Set THP to a non-aggressive mode to avoid latency spikes:

echo madvise | sudo tee /sys/kernel/mm/transparent_hugepage/enabled
echo never   | sudo tee /sys/kernel/mm/transparent_hugepage/defrag

These runtime changes do not survive a reboot. Make them persistent with a small systemd unit, a tuned profile or the transparent_hugepage=madvise kernel argument.

8. Step 4: Add the Apache Cassandra Repository

sudo tee /etc/yum.repos.d/cassandra.repo > /dev/null <<'EOF'

[cassandra]

name=Apache Cassandra baseurl=https://redhat.cassandra.apache.org/50x/ gpgcheck=1 repo_gpgcheck=1 gpgkey=https://downloads.apache.org/cassandra/KEYS EOF sudo dnf clean all sudo dnf makecache

50x is the 5.0 release line. Use 41x for 4.1.

Rocky Linux 10 note: RHEL 10 family systems apply a stricter system-wide cryptographic policy that rejects SHA-1 signatures by default. If dnf makecache fails while importing the Cassandra signing key, see the first two rows of the troubleshooting table before changing any policy.

9. Step 5: Install Cassandra

sudo dnf -y install cassandra

Review what the package created:

rpm -ql cassandra | head -30
cat /etc/security/limits.d/cassandra.conf
id cassandra

Reload systemd so it picks up the service definition:

sudo systemctl daemon-reload

Do not start Cassandra yet. Settings such as cluster_name should be set before the first start, because changing it later on a node that already has data requires extra steps.

10. Step 6: Configure cassandra.yaml

Back up the default file, then edit it:

sudo cp /etc/cassandra/conf/cassandra.yaml /etc/cassandra/conf/cassandra.yaml.orig
sudo vim /etc/cassandra/conf/cassandra.yaml

Set or verify these keys for a single-node lab (replace 10.10.10.11 with the node’s own IP):

cluster_name: 'BCK Cassandra Cluster'
num_tokens: 16

seed_provider:
  - class_name: org.apache.cassandra.locator.SimpleSeedProvider
    parameters:
      - seeds: "10.10.10.11:7000"

listen_address: 10.10.10.11        # internode communication
rpc_address: 10.10.10.11           # client (CQL) connections
# broadcast_rpc_address: only needed with NAT or when rpc_address is 0.0.0.0

endpoint_snitch: GossipingPropertyFileSnitch

native_transport_port: 9042
storage_port: 7000

Key points:

SettingWhy it matters
cluster_nameMust be identical on all nodes; hard to change after first start
seedsContact points for gossip discovery; not a “master”
listen_address / rpc_addressUse a real IP. Never leave localhost on a node that other machines must reach
endpoint_snitchGossipingPropertyFileSnitch is the recommended production choice and reads the datacenter and rack from a properties file
num_tokensLeave the default for the release unless you have a reason to change it

Set the datacenter and rack names:

sudo tee /etc/cassandra/conf/cassandra-rackdc.properties > /dev/null <<'EOF'
dc=dc1
rack=rack1
EOF

Choose these names carefully. Changing a datacenter name after data exists is disruptive.

Heap size

By default Cassandra sizes its heap automatically, which is acceptable for a lab. For production, set it explicitly in /etc/cassandra/conf/jvm-server.options (for example -Xms8G and -Xmx8G, with both values equal) and follow the current sizing guidance for your release. Leave the rest of the machine’s memory for the operating system page cache.

11. Step 7: Start Cassandra and Verify

sudo systemctl enable --now cassandra
sudo systemctl status cassandra --no-pager

The first start can take a minute or two. Watch the log until you see that the node is listening for CQL clients:

sudo tail -f /var/log/cassandra/system.log

Then check the cluster state:

nodetool status

Expected output shows one node with status UN (Up / Normal):

Datacenter: dc1
===============
Status=Up/Down
|/ State=Normal/Leaving/Joining/Moving
--  Address       Load        Tokens  Owns    Host ID      Rack
UN  10.10.10.11   110 KiB     16      100.0%  xxxxxxxx...  rack1

Confirm the CQL shell connects:

cqlsh 10.10.10.11 9042

If cqlsh fails with a Python error on Rocky Linux 10, jump to the troubleshooting table.

12. Step 8: Firewall and SELinux

Ports

PortPurposeExpose to
9042CQL native transport (clients)Application servers only
7000Internode communicationOther Cassandra nodes only
7001Internode with TLSOther Cassandra nodes only
7199JMX (nodetool)Localhost only; do not open
# Client access from the application subnet
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.10.20.0/24" port protocol="tcp" port="9042" accept'

# Internode traffic from the Cassandra subnet
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.10.10.0/24" port protocol="tcp" port="7000" accept'
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.10.10.0/24" port protocol="tcp" port="7001" accept'

sudo firewall-cmd --reload
sudo firewall-cmd --list-rich-rules

SELinux

Keep SELinux in enforcing mode. With the default RPM paths (/var/lib/cassandra, /var/log/cassandra), nothing extra is normally required.

getenforce
sudo ausearch -m avc -ts recent          # look for denials after start-up

If you place data on a separate mount such as /data/cassandra, give it the correct ownership and let SELinux relabel it:

sudo mkdir -p /data/cassandra/{data,commitlog,saved_caches,hints}
sudo chown -R cassandra:cassandra /data/cassandra
sudo restorecon -Rv /data/cassandra

Then point data_file_directories, commitlog_directory, saved_caches_directory and hints_directory in cassandra.yaml to the new paths. If you still see AVC denials, review them with ausearch and create a targeted policy rather than disabling SELinux. See Docker on Rocky Linux 10 with SELinux for the same troubleshooting mindset.

13. Step 9: Enable Authentication

A default Cassandra install accepts anyone. Turn on password authentication and authorization.

Edit /etc/cassandra/conf/cassandra.yaml:

authenticator: PasswordAuthenticator
authorizer: CassandraAuthorizer

Restart the node:

sudo systemctl restart cassandra

Log in with the built-in superuser, which starts as cassandra / cassandra:

cqlsh -u cassandra -p cassandra 10.10.10.11

Immediately create your own superuser, then remove the default account’s privileges:

CREATE ROLE bckadmin WITH PASSWORD = 'ChangeMe_UseALongPassword!'
  AND LOGIN = true AND SUPERUSER = true;

-- reconnect as bckadmin, then neutralize the default account
ALTER ROLE cassandra WITH PASSWORD = 'A_Long_Random_Unused_Password'
  AND SUPERUSER = false AND LOGIN = false;

Create a least-privilege role for an application:

CREATE ROLE appuser WITH PASSWORD = 'AppStrongPassword!' AND LOGIN = true;
GRANT SELECT ON KEYSPACE shop TO appuser;
GRANT MODIFY ON KEYSPACE shop TO appuser;

Set the replication of the system_auth keyspace to match your cluster. On a single node this is already fine; in a multi-node cluster raise it so logins survive a node failure:

ALTER KEYSPACE system_auth WITH replication =
  {'class': 'NetworkTopologyStrategy', 'dc1': 3};

Then run nodetool repair system_auth on each node.

For production, also enable TLS for client-to-node and node-to-node traffic (client_encryption_options and server_encryption_options in cassandra.yaml) using certificates from your CA.

14. Step 10: First Keyspace, Table and Query

CREATE KEYSPACE IF NOT EXISTS shop
  WITH replication = {'class': 'NetworkTopologyStrategy', 'dc1': 1}
  AND durable_writes = true;

USE shop;

CREATE TABLE IF NOT EXISTS orders_by_customer (
    customer_id  uuid,
    order_time   timestamp,
    order_id     uuid,
    total        decimal,
    status       text,
    PRIMARY KEY ((customer_id), order_time, order_id)
) WITH CLUSTERING ORDER BY (order_time DESC, order_id ASC);

INSERT INTO orders_by_customer (customer_id, order_time, order_id, total, status)
VALUES (11111111-1111-1111-1111-111111111111, toTimestamp(now()), uuid(), 250000, 'PAID');

SELECT * FROM orders_by_customer
WHERE customer_id = 11111111-1111-1111-1111-111111111111
LIMIT 10;

Notice the design: the table is shaped around one query (“latest orders for a customer”). The partition key customer_id keeps each customer’s orders together, and the clustering columns sort them newest first.

Rule of thumbReason
Design one table per query patternNo joins, so denormalize
Keep partitions reasonably sizedHuge partitions hurt latency and repairs
Avoid ALLOW FILTERING in productionIt forces expensive scans
Use NetworkTopologyStrategy even for a single datacenterMakes future expansion easier
Use replication factor 3 in production clustersSurvives a node failure with quorum reads and writes

15. Expanding to a 3-Node Cluster

Prepare three Rocky Linux 10 hosts with identical OS tuning, Java and Cassandra installation (Steps 1 to 5). Example addresses: 10.10.10.11, 10.10.10.12, 10.10.10.13.

On every node, set:

cluster_name: 'BCK Cassandra Cluster'      # identical everywhere
seed_provider:
  - class_name: org.apache.cassandra.locator.SimpleSeedProvider
    parameters:
      - seeds: "10.10.10.11:7000,10.10.10.12:7000"
listen_address: <this node's own IP>
rpc_address:    <this node's own IP>
endpoint_snitch: GossipingPropertyFileSnitch

And set dc=dc1 with rack=rack1, rack2 and rack3 in cassandra-rackdc.properties on each node respectively. Open ports 7000 and 7001 between all three nodes.

Start the nodes one at a time, waiting for each to show UN before starting the next:

# node1 first, then node2, then node3
sudo systemctl enable --now cassandra
nodetool status

If a node was started earlier with different settings and holds test data, stop it and clear /var/lib/cassandra/data, commitlog, saved_caches and hints before joining it to the cluster.

After all nodes join, raise the replication of your keyspaces to 3:

ALTER KEYSPACE shop WITH replication = {'class': 'NetworkTopologyStrategy', 'dc1': 3};
nodetool repair shop         # run on each node after changing replication
CheckCommandHealthy result
Cluster membershipnodetool statusAll nodes UN
Schema agreementnodetool describeclusterOne schema version
Gossip statenodetool gossipinfoAll peers NORMAL
Pending worknodetool tpstatsNo growing pending or blocked queues

16. Backup and Maintenance

Snapshots

A snapshot is a fast, hard-link based copy of SSTables:

nodetool snapshot -t before_change shop
nodetool listsnapshots
nodetool clearsnapshot -t before_change

Snapshots live inside the data directory on the same disk, so copy them to remote storage for real protection. A restore means placing the snapshot files back into the table directory (or using sstableloader) and refreshing, and it should be rehearsed on a spare cluster.

Routine care

TaskCommandFrequency
Repair (anti-entropy)nodetool repair -prRegularly, within the gc_grace_seconds window
Node healthnodetool status, nodetool infoDaily or via monitoring
Table statisticsnodetool tablestats shopWhen tuning
Compaction activitynodetool compactionstatsWhen disk or latency looks odd
Log review/var/log/cassandra/system.log and debug.logContinuously via log shipping

Repairs are essential in Cassandra because they reconcile replicas that missed writes. Schedule them, or use a repair scheduler tool.

Upgrade and node removal

sudo dnf upgrade cassandra          # read release notes first; upgrade one node at a time
nodetool drain                      # before stopping a node for maintenance
nodetool decommission               # gracefully remove a live node from the cluster

17. Useful Files and Commands

ItemLocation or command
Main config/etc/cassandra/conf/cassandra.yaml
JVM options/etc/cassandra/conf/jvm-server.options (and jvm17-server.options)
Datacenter and rack/etc/cassandra/conf/cassandra-rackdc.properties
Data directory/var/lib/cassandra/data
Commit log/var/lib/cassandra/commitlog
Main log/var/log/cassandra/system.log
Service control`sudo systemctl status
CQL shellcqlsh <ip> 9042 -u <user>
Versioncassandra -v or nodetool version
Cluster statenodetool status
Flush memtablesnodetool flush

18. Troubleshooting

SymptomLikely causeFix
dnf makecache or install fails importing the Cassandra GPG keyRHEL 10 family crypto policy rejects SHA-1 signatures used by the keyVerify the key fingerprint against Apache’s published KEYS file. Prefer installing from the tarball or a manually verified RPM. As a last resort and temporarily, relax the policy (update-crypto-policies --set DEFAULT:SHA1), install, then revert with update-crypto-policies --set DEFAULT
Repository metadata signature check (repo_gpgcheck) failsSame policy issue on the repository metadataSame as above, or set repo_gpgcheck=0 only after verifying downloaded packages by checksum and signature
cqlsh fails with No module named 'asyncore' or a driver import errorRocky Linux 10 ships Python 3.12, and older bundled drivers depend on modules removed from PythonUpdate to a Cassandra release whose bundled cqlsh supports Python 3.12, or point cqlsh to another supported Python (for example through the CQLSH_PYTHON variable), or run cqlsh from a container
Unsupported major.minor or Java startup errorWrong Java version for the Cassandra releaseInstall java-17-openjdk-headless for 5.0 and select it with alternatives --config java
Service shows active but cqlsh says connection refusedCassandra still starting, or rpc_address bound to another IPWait and watch system.log; confirm rpc_address and use that IP with cqlsh
Cannot start node if snitch's data center (X) differs from previous data center (Y)Datacenter name changed after first startRestore the original name in cassandra-rackdc.properties, or clear data on a fresh node
Saved cluster name Test Cluster != configured namecluster_name changed after the first startRevert the name, or wipe the node’s data directories if it holds no data you need
Node stays DN (down) in nodetool statusGossip port blocked, wrong seed or clock problemCheck firewalld on port 7000, verify seeds, and check chronyc tracking
Nodes cannot see each otherlisten_address set to localhost or wrong IPUse each node’s real private IP and restart
Permission denied errors in the logWrong ownership or SELinux label after moving directorieschown -R cassandra:cassandra, then restorecon -Rv; inspect with ausearch -m avc
JVM cannot lock memory or too many open filesLimits not appliedCheck /etc/security/limits.d/cassandra.conf, then restart via systemd
Heavy GC pauses and timeoutsHeap too large or too small, swap activeSet equal -Xms/-Xmx, disable swap, review gc.log
Read timeouts under loadLarge partitions, tombstones, or ALLOW FILTERING queriesReview the data model; use nodetool tablestats and tablehistograms
Disk fills unexpectedlyOld snapshots, compaction backlognodetool listsnapshots and clearsnapshot; check compactionstats
Login fails after enabling authenticationWrong role or system_auth replicated to too few nodesUse the default superuser to recover; raise system_auth replication and repair

19. FAQ

Is Apache Cassandra free?
Yes. It is open source under the Apache 2.0 licence. Commercial distributions and managed services exist if you want support.

Can I run Cassandra on a single node?
Yes, for development and learning. Production deployments normally use at least three nodes with a replication factor of 3.

Which Java version does Cassandra 5.0 use?
Java 11 or 17. This guide uses OpenJDK 17, which is available in the Rocky Linux 10 repositories.

Cassandra or MongoDB?
Cassandra excels at very high write volume, multi-node availability and predictable scaling for query-designed tables. MongoDB offers a more flexible document model with richer ad-hoc querying. See Install MongoDB on Rocky Linux 10.2 for the alternative.

Does Cassandra support vector search?
Version 5.0 introduced a vector data type and vector search using Storage-Attached Indexes, which makes it usable for some similarity search workloads. For a comparison with dedicated engines, read Vector Databases Explained.

Can Cassandra store time series data?
Yes, and it is widely used for it, though you must design partitions carefully (for example bucketing by time). For a comparison with dedicated time series databases, see InfluxDB vs Prometheus vs TimescaleDB.

Why do I have to run repairs?
Cassandra favours availability, so a replica can miss a write while it is down. Repairs reconcile differences between replicas and must run regularly to keep data consistent and to prevent deleted data from reappearing.

20. Conclusion

You now have Apache Cassandra 5.0 running on Rocky Linux 10 with a tuned operating system, a configured cassandra.yaml, authentication, firewalld and SELinux handled correctly, a first data model and a path to a 3-node cluster. Before going to production, add TLS, set an explicit heap size, schedule repairs and backups, set up monitoring for nodetool metrics and GC, and rehearse a node replacement.

(Visited 3 times, 1 visits today)

You may also like