Cassandra Fundamentals
Cassandra ๋
Apache Cassandra ๋ Facebook ์์ ์์๊ณ ํ์ฌ๋ Apache ์ฌ๋จ์์ ๊ด๋ฆฌํ๊ณ ์๋ ์คํ์์ค ๋ถ์ฐ NoSQL Database ์ด๋ค. Java ๋ก ์์ฑ๋์ด ์์ผ๋ฉฐ ๋๊ท๋ชจ ๋ฐ์ดํฐ ์ฒ๋ฆฌ, High Availability, Scalability ๋ฅผ SPOF ์์ด ์ ๊ณตํ๊ธฐ ์ํด Amazon DynamoDB ์ ๋ถ์ฐ ์คํ ๋ฆฌ์ง ๋์์ธ๊ณผ Google Bigtable ์ ๋ฐ์ดํฐ ๋ชจ๋ธ์ ์กฐํฉํ์ฌ ์ค๊ณ๋์๋ค.
Cassandra ํน์ง
- Masterless ๋ฐฉ์์ผ๋ก ๊ตฌ์ฑ๋์ด Cluster ์ค๋จ ์์ด ๋ ธ๋๋ฅผ ์ถ๊ฐ/์ญ์ ํ์ฌ ์ํ ํ์ฅ/์ถ์๊ฐ ๊ฐ๋ฅํ๋ค.
- ๋ฐ์ดํฐ๋ฅผ ์ฌ๋ฌ ๋ ธ๋์ ๋ถ์ฐ ๋ฐ ๋ณต์ ํ์ฌ ์ ์ฅํ๋ค.
- CQL(Cassandra Query Language) ์ด๋ผ๋ SQL ๊ณผ ์ ์ฌํ ์ฟผ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ง๋ง JOIN ๋ฑ ๋ณต์กํ ์ฐ์ฐ์ ์ง์ํ์ง ์๋๋ค.
- Column Family Data Model ์ ์ฌ์ฉํจ์ผ๋ก์จ WHERE ์ ์ Key ๋ง ์ฌ์ฉ ๊ฐ๋ฅํ๋ฏ ๋ณต์กํ ์ฟผ๋ฆฌ๋ ์ง์ํ์ง ์์ง๋ง ๋จ์ํ ๊ฒ์ ์กฐ๊ฑด์ผ๋ก ๋๋์ ๋ฐ์ดํฐ๋ฅผ ๊ฒ์ํ๊ธฐ ์ ํฉํ๋ค.
Cassandra Architecture
Cassandra ๋ ๋ชจ๋ ๋
ธ๋๊ฐ ์๋ก ์ํตํ ์ ์๋ Peer-to-Peer ์ํคํ
์ฒ์ ๋ชจ๋ ๋
ธ๋๊ฐ ๋์ผํ ์ญํ ์ ํ๋ Masterless ๋ฐฉ์์ผ๋ก ํด๋ฌ์คํฐ(๋๋ Ring)๋ฅผ ์ด๋ฃจ์ด ๋ถ์ฐ ์์คํ
์ ๊ตฌ์ฑํ๋ค. ๊ฐ ๋
ธ๋๊ฐ ๋๋ฑํ ์ญํ ์ ์ํํ ์ ์๊ธฐ ๋๋ฌธ์ ํด๋ฌ์คํฐ์ ๋
ธ๋๋ฅผ ์ถ๊ฐํจ์ผ๋ก์จ ํด๋ฌ์คํฐ๋ฅผ ์ํ์ผ๋ก ํ์ฅํ๊ธฐ ์ฉ์ดํ๋ค.
Cassandra ์ ์ ์ฅ๋ ๋ฐ์ดํฐ๋ ํด๋ฌ์คํฐ ์ ์ฒด์ ๊ท ๋ฑํ๊ฒ ๋ถ์ฐ๋๊ณ , ๊ฐ ๋
ธ๋๊ฐ ๋
๋ฆฝ์ ์ผ๋ก ์ฝ๊ธฐ์ ์ฐ๊ธฐ ์์
์ ์ฒ๋ฆฌํ ์ ์๋ค.
- Cassandra Cluster = Cassandra Ring
- Data Center = Rack ์ ๋ ผ๋ฆฌ์ ์ธ ์งํฉ
- Rack = Node ์ ๋ ผ๋ฆฌ์ ์ธ ์งํฉ์ผ๋ก ๋ฐ์ดํฐ ๋ณต์ ๋ณธ์ด ๋ค๋ฅธ ๋ ผ๋ฆฌ์ Rack ์ ๋ถ์ฐ๋๋๋ก ์ฌ์ฉ
- Node = Cassandra ๋ฅผ ํธ์คํ ํ๋ ์๋ฒ ์ธ์คํด์ค๋ก ๋ ธ๋๋ผ๋ฆฌ Gossip Protocol ์ ํตํด ํต์
- Keyspace = RDBMS ์ Database ์ญํ ์ ์ํํ๋ฉฐ ํ๋ ์ด์์ Column Family ๋ฅผ ํฌํจ
- Column Family = RDBMS ์ Table ์ญํ ์ ์ํํ๋ฉฐ ๊ฐ Row ๋ง๋ค ๋ค๋ฅธ Column ์ ๊ฐ์ง ์ ์์
- Column = Key-Value ํํ๋ก ์ ์ฅ๋๋ฉฐ Key(Column Name) ์ ์ ์ , ๋์ ์์ฑ ๊ฐ๋ฅ
Cassandra Data Model
Cassandra ์ ์ ์ฅ๋๋ ๋ฐ์ดํฐ๋ Column Family ์ ์ ์ฅ๋๋๋ฐ ๊ฐ Row ๊ฐ Key-Value ๋ก ์ด๋ฃจ์ด์ง ์ฌ๋ฌ๊ฐ์ Column ์ ๊ฐ์ง ์ ์๋ค. RDBMS ์ ๋ฌ๋ฆฌ Column ์ด ๋ชจ๋ ์กด์ฌํ์ง ์์๋ ๋๋ค.
Cassandra ์ Primary Key ๋ 1๊ฐ ์ด์์ Partition Key(Row Key) ์ 0๊ฐ ์ด์์ Cluster Key ๋ก ๊ตฌ์ฑ๋๋ค. Cassandra ๋ ๋ฐ์ดํฐ๋ฅผ ๋ถ์ฐ ๋ฐ ๋ณต์ ํ์ฌ ์ ์ฅํ๊ธฐ ์ํด Partition Key(Row Key) ๋ฅผ ์ฌ์ฉํด Hash Token ์ ์์ฑํ๊ณ ํด๋น Token ์ ๋ง๋ ๋
ธ๋์ ๋ฐ์ดํฐ๋ฅผ ๋ถ์ฐ ๋ฐ ์ ์ฅํ๋ค. Cluster Key(Sort Key) ๋ ๋ฐ์ดํฐ๋ฅผ ์ ๋ ฌํ ๋ ์ฌ์ฉํ๋ Key ๋ก ๋ฐ์ดํฐ๊ฐ ์ ์ฅ๋ ๋ ์ ๋ ฌํด์ ์ ์ฅํ๋ค.
Installing Cassandra with Docker
Cassandra Node 2๊ฐ ์์ฑ
docker pull cassandra:latest
docker network create cassandra
docker run \
--name cassandra-node1 \
--network cassandra \
--rm -d cassandra:latest
docker run \
--name cassandra-node2 \
--network cassandra \
-e CASSANDRA_SEEDS=cassandra-node1 \
--rm -d cassandra:latest
meatsby ๐พ ๎ฐ ~ ๎ฐ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
999d64b6b046 cassandra:latest "docker-entrypoint.sโฆ" 6 seconds ago Up 6 seconds 7000-7001/tcp, 7199/tcp, 9042/tcp, 9160/tcp cassandra-node2
bc4d85c6c785 cassandra:latest "docker-entrypoint.sโฆ" 2 minutes ago Up 2 minutes 7000-7001/tcp, 7199/tcp, 9042/tcp, 9160/tcp cassandra-node1
meatsby ๐พ ๎ฐ ~ ๎ฐ docker exec -it cassandra-node1 bash
root@bc4d85c6c785:/# nodetool status
Datacenter: datacenter1
=======================
Status=Up/Down
|/ State=Normal/Leaving/Joining/Moving
-- Address Load Tokens Owns (effective) Host ID Rack
UN 172.20.0.3 119.68 KiB 16 100.0% 8c056774-d514-4991-bf03-0d8e79fd74e0 rack1
UN 172.20.0.2 119.81 KiB 16 100.0% 3a905cff-d969-4f67-a37c-6ec3c7dc171b rack1
root@bc4d85c6c785:/# cqlsh
Connected to Test Cluster at 127.0.0.1:9042
[cqlsh 6.2.0 | Cassandra 5.0.3 | CQL spec 3.4.7 | Native protocol v5]
Use HELP for help.
Keyspace ์์ฑ ๋ฐ ๋ฐ์ดํฐ ์ ์ฅ
-- Create a keyspace
CREATE KEYSPACE IF NOT EXISTS test WITH REPLICATION = { 'class' : 'SimpleStrategy', 'replication_factor' : '2' };
-- Create a table
CREATE TABLE IF NOT EXISTS test_table (
userid text PRIMARY KEY,
item_count int,
last_update_timestamp timestamp
);
-- Insert some data
INSERT INTO test_table
(userid, item_count, last_update_timestamp)
VALUES ('9876', 2, toTimeStamp(now()));
INSERT INTO test_table
(userid, item_count, last_update_timestamp)
VALUES ('1234', 5, toTimeStamp(now()));
root@bc4d85c6c785:/# nodetool status
Datacenter: datacenter1
=======================
Status=Up/Down
|/ State=Normal/Leaving/Joining/Moving
-- Address Load Tokens Owns (effective) Host ID Rack
UN 172.20.0.3 112.97 KiB 16 100.0% 8c056774-d514-4991-bf03-0d8e79fd74e0 rack1
UN 172.20.0.2 95.8 KiB 16 100.0% 3a905cff-d969-4f67-a37c-6ec3c7dc171b rack1
'replication_factor' : '2'
๋ก ์ง์ ํด๋จ๊ธฐ ๋๋ฌธ์ ๋ชจ๋ ๋ ธ๋์ ์ ์ฅ๋ ๋ชจ์ต
meatsby ๐พ ๎ฐ ~ ๎ฐ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
999d64b6b046 cassandra:latest "docker-entrypoint.sโฆ" 5 minutes ago Up 5 minutes 7000-7001/tcp, 7199/tcp, 9042/tcp, 9160/tcp cassandra-node2
bc4d85c6c785 cassandra:latest "docker-entrypoint.sโฆ" 7 minutes ago Up 7 minutes 7000-7001/tcp, 7199/tcp, 9042/tcp, 9160/tcp cassandra-node1
meatsby ๐พ ๎ฐ ~ ๎ฐ docker stop 99
99
meatsby ๐พ ๎ฐ ~ ๎ฐ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bc4d85c6c785 cassandra:latest "docker-entrypoint.sโฆ" 7 minutes ago Up 7 minutes 7000-7001/tcp, 7199/tcp, 9042/tcp, 9160/tcp cassandra-node1
meatsby ๐พ ๎ฐ ~ ๎ฐ docker exec -it cassandra-node1 bash
root@bc4d85c6c785:/# nodetool status
Datacenter: datacenter1
=======================
Status=Up/Down
|/ State=Normal/Leaving/Joining/Moving
-- Address Load Tokens Owns (effective) Host ID Rack
DN 172.20.0.3 112.97 KiB 16 100.0% 8c056774-d514-4991-bf03-0d8e79fd74e0 rack1
UN 172.20.0.2 95.8 KiB 16 100.0% 3a905cff-d969-4f67-a37c-6ec3c7dc171b rack1
root@bc4d85c6c785:/# cqlsh
Connected to Test Cluster at 127.0.0.1:9042
[cqlsh 6.2.0 | Cassandra 5.0.3 | CQL spec 3.4.7 | Native protocol v5]
Use HELP for help.
cqlsh> use test;
cqlsh:test> select * from test_table;
userid | item_count | last_update_timestamp
--------+------------+---------------------------------
1234 | 5 | 2025-03-26 15:38:56.057000+0000
9876 | 2 | 2025-03-26 15:38:55.600000+0000
(2 rows)
- Node2 ๊ฐ ๋ค์ด๋์ง๋ง ์ฌ์ ํ ๋ฐ์ดํฐ๊ฐ ์กฐํ๋๋ ๋ชจ์ต
UN
(Up Normal): ๋ ธ๋๊ฐ ์ ์์ ์ผ๋ก ์๋ ์ค (Up & Normal)DN
(Down Normal): ๋ ธ๋๊ฐ ์ ์์ ์ผ๋ก ํ ํด๋ก์ง์ ์ํ์ง๋ง, ํ์ฌ ๋ค์ด๋จ (Down & Normal)UJ
(Up Joining): ์๋ก์ด ๋ ธ๋๊ฐ ํด๋ฌ์คํฐ์ ํฉ๋ฅ ์คUL
(Up Leaving): ๋ ธ๋๊ฐ ํด๋ฌ์คํฐ์์ ๋ ๋๋ ์คUM
(Up Moving): ๋ ธ๋๊ฐ ํ ํฐ์ ์ด๋ํ๋ ์ค