Apache Cassandra ํบ์๋ณด๊ธฐ - 1ํธ
Apache Cassandra ํบ์๋ณด๊ธฐ - 1ํธ ๊ด๋ จ
1. ๋ค์ด๊ฐ๊ธฐ์ ์์
์๋ ํ์ธ์. NHN์ํฐํ ์ธ๋จผํธ ์์ธ์ง์ ๋๋ค.
์ต๊ทผ ๋ช ๋ฌ ๋์ ์ ๋ฌด์์ ์ด์ ๋ก Cassandra๋ฅผ ๊ณต๋ถ ํ ๊ธฐํ๊ฐ ์์์ต๋๋ค. ์ต๊ทผ Cassandra๊ฐ ์ฌ๊ธฐ์ ๊ธฐ์ ๋๋ฆ HOTํ ๋์ ์ ๋ฐ๊ณ ์๊ธฐ๋ ํ๊ณ , ์ง์ ๊ณต๋ถํ๋ ๋์ ๊ฒช์๋ ์ด๋ฐ์ ๋ฐ ์ ๋ก์ฌํญ์ด๋ ํน์ง๋ค์ ๊ณต์ ํ๋ค๋ฉด ํ์ฌ๋ ๋ค๋ฅธ ๋ถ๋ค์ด ์กฐ๊ธ์ด๋ผ๋ ์ฝ์ง์ ํผํ์ค ์ ์์ง ์์๊น ์ถ์ ์๊ฐ์ ๊ทธ๊ฐ ์ ๊ฐ ๊ฒช์๋ ์ ๋ก์ฌํญ๋ค์ ๋ฐ์ํ์ฌ ์ต๋ํ ๊ฐ๋ตํ ์ ๋ฆฌํ ๋ด์ฉ์ ๊ณต์ ๋๋ฆฌ๊ณ ์ ํฉ๋๋ค. ๋ง์ฝ Cassandra์ ๋ํด ์ ๋๋ก ๊น์ ๋ด์ฉ์ ์๊ณ ์ถ์ผ์๋ค๋ฉด ํ์ฌ ์์ค์ ํ๋งค๋๊ณ ์๋ ๊ตญ๋ด ๋ฒ์ญ์๋ค ๋ณด๋ค๋, ๋๋๋ก์ด๋ฉด DataStax์ ๊ณต์ ๋ฌธ์๋ Learning Apache Cassandra, Mastering Apache Cassandra, Cassandra High Availability์ ๊ฐ์ ์ธ๊ตญ ๋์๋ฅผ ๋ณด์๋ ๊ฒ์ ์ถ์ฒํด ๋๋ฆฝ๋๋ค. (๊ตญ๋ด ๋ฒ์ญ์๋ค์ด ๋ค๋ฃจ๋ Cassandra์ ๋ฒ์ ์ 0.X๋์ฌ์ ํ์ฌ์๋ ๋ง์ ์ฐจ์ด๊ฐ ์์ต๋๋ค. ์ฌ์ค ๊ฐ์ธ์ ์ผ๋ก ์ด ๋ถ๋ถ ๋๋ฌธ์ ๋ง์ ๊ณ ์์ ํ์์ต๋๋ค.)
2. Cassandra์ ํน์ง
Cassandra๋ scalability์ high availability์ ์ต์ ํ๋ ๋ํ์ ์ธ ๋ถ์ฐํ Data storage์ ๋๋ค. Consistent hashing์ ์ด์ฉํ Ring ๊ตฌ์กฐ์ Gossip protocol์ ๊ตฌํํ์์ผ๋ฉฐ, ๋๋ฌธ์ ๊ฐ ๋ ธ๋ ์ฅ๋น๋ค์ ์ถ๊ฐ, ์ ๊ฑฐ ๋ฑ์ด ์์ ๋กญ๊ณ , ๋ฐ์ดํฐ์ผํฐ๊น์ง ๊ณ ๋ ค ํ ์ ์๋ ๋ฐ์ดํฐ ๋ณต์ ์ ์ฑ ์ ์ฌ์ฉํ์ฌ ์์ ์ฑ ์ธก๋ฉด์์ ๋ง์ ์ฅ์ ์ ๊ฐ์ง๊ณ ์์ต๋๋ค. Cassandra๋ฅผ ์ด์ฉํ๋ฉด Sharding์ ๊ณ ๋ คํด์ผ ํ ํ์๋ ์๊ณ Master-Slave ์ ๊ฐ์ ์ ์ฑ ์ด ์์ด๋ ์ฅ์ ์ ๋์ํ ์ ์์ผ๋ฉฐ, ํ์์ ๋ฐ๋ผ ์ฅ๋น๋ค์ ๋๋ฆฌ๊ณ ์ค์ด๋ ๋ฐ ํฐ ๋น์ฉ์ด ๋ค์ง ์์ต๋๋ค.
๋ฌผ๋ก ๊ทธ๋ ๋ค๊ณ ํด์ Cassandra๊ฐ ์๋ฒฝํ ์๋ฃจ์ ์ ์๋๋๋ค. ๋น์ฐํ ์ด์ผ๊ธฐ์ง๋ง ๋ชจ๋ ์ผ์๋ trade off๊ฐ ์๋ฏ์ด ์ ๋ฌํ ๊ฐ๋ ฅํ ๊ธฐ๋ฅ๋ค์ด ๊ตฌํ๋จ์ผ๋ก์จ ๋ฐ๋๋ก ์๋ง์ ๋จ์ ๋ค ์ญ์ ๋ฐ์ํ์๊ธฐ ๋๋ฌธ์ ๋๋ค. Cassandra๋ Join์ด๋ Transaction์ ์ง์ํ์ง ์๊ณ , Index ๋ฑ์ ๊ฒ์์ ์ํ ๊ธฐ๋ฅ๋ ๋งค์ฐ ๋จ์ถํฉ๋๋ค. ๊ฒ๋ค๊ฐ Cassandra์ ๊ตฌ์กฐ์ RDBMS์ ๊ฐ์ Paging์ ๊ตฌํํ๋ ๊ฒ์ด ํ๋ค๊ณ Keyspace(RDBMS์ DB์ ๊ฐ์)๋ Table ๋ฑ์ ๊ณผ๋ํ๊ฒ ์์ฑํ ๊ฒฝ์ฐ Memory Overflow๊ฐ ๋ฐ์ํ ์ ์์์ ๊ณ ๋ คํ์ฌ์ผ ํฉ๋๋ค.
๋ฐ๋ผ์ Cassandra๊ฐ ๊ธฐ์กด์ RDBMS๋ค์ ์๋ฒฝํ ๋์ฒดํ์ด๋ผ๊ณ ํ ์๋ ์์ผ๋ฏ๋ก, ๊ฐ๋ฐํ๊ฒ ๋ ์ ํ์ ๊ธฐ๋ฅ๊ณผ ํน์ง์ ๋ฐ๋ผ Cassandra๋ฅผ ์ฌ์ฉํ ๊ฒ์ธ์ง RDBMS๋ฅผ ์ฌ์ฉํ ๊ฒ์ธ์ง๋ฅผ ์ ์คํ ๊ฒฐ์ ํ์ฌ์ผ ํฉ๋๋ค.
3. Cassandra Data Structure
Cassandra์ ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ ๋น๊ต์ ๊ฐ๋จํฉ๋๋ค. ์ต์์์ ๋ ผ๋ฆฌ์ Data ์ ์ฅ์์ธ Keyspace๊ฐ ์๊ณ , Keyspace ์๋์๋ Table์ด ์กด์ฌํฉ๋๋ค. Table์ ๋ค์์ Row๋ค๋ก ๊ตฌ์ฑ๋์ด์์ผ๋ฉฐ ๊ฐ Row๋ Key-Value๋ก ์ด๋ฃจ์ด์ง Column๋ค๋ก ๊ตฌ์ฑ๋ฉ๋๋ค. RDBMS์ DB-Table-Row-Column์ ํํ์ ์ ์ฌํ ๊ตฌ์กฐ๋ฅผ ํ๊ณ ์๋ค๋ ๊ฑธ ์ ์ ์์ต๋๋ค. ๋๊ตฌ๋ Cassandra๋ ํ์ฌ CQL (Cassandra Query Language)์ ์ง์ํ๊ณ ์์ผ๋ฏ๋ก, ๊ธฐ์กด์ RDBMS๋ฅผ ์ฌ์ฉํ ์ ์ด ์๋ ์ฌ๋๋ค์ด๋ผ๋ฉด ํฐ ๊ฑฐ๋ถ๊ฐ ์์ด Cassandra๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค. (๋ฌผ๋ก ๊ทธ๋ฅ ๊ทธ๋ ๊ฒ ์ฐ๋ฉด ๋งํ๊ฒ ์ง๋ง์.)
๊ทธ๋ ๋ค๋ฉด Cassandra๋ฅผ ์ ๋๋ก ์ฌ์ฉํ๊ธฐ ์ํด์, ์ฐ๋ฆฌ๋ ๋จผ์ Cassandra๊ฐ ์ด๋ป๊ฒ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๋์ง๋ถํฐ ์์๋ณผ ํ์๊ฐ ์์ต๋๋ค.
Cassandra๋ ๊ธฐ๋ณธ์ ์ผ๋ก Ring ๊ตฌ์กฐ๋ฅผ ๋ ๊ณ ์์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ Ring์ ๊ตฌ์ฑํ๋ ๊ฐ ๋ ธ๋์ Data๋ฅผ ๋ถ์ฐํ์ฌ ์ ์ฅํฉ๋๋ค. ๊ทธ๋ ๋ค๋ฉด ๋ฐ์ดํฐ๋ฅผ ๋ถ์ฐํ๋ ๊ธฐ์ค์ ๋ญ๊น์? Partition Key๋ผ๊ณ ๋ถ๋ฆฌ๋(์ค์ Cassandra Data Layer์์ Row Key๋ผ๊ณ ๋ถ๋ฆฌ๋) ๋ฐ์ดํฐ์ hash๊ฐ์ ๊ธฐ์ค์ผ๋ก Data๋ฅผ ๋ถ์ฐํ๊ฒ ๋ฉ๋๋ค.
์ฒ์ ๊ฐ ๋ ธ๋๊ฐ Ring์ ์ฐธ์ฌํ๊ฒ ๋๋ฉด, Cassandra์ conf/cassandra.yaml์ ์ ์๋ ๊ฐ ์ค์ ์ ํตํ์ฌ ๊ฐ ๋ ธ๋๋ง๋ค ๊ณ ์ ์ hash ๊ฐ ๋ฒ์๋ฅผ ๋ถ์ฌ ๋ฐ์ต๋๋ค. ๊ทธ๋ฐ ๋ค์, ์ธ๋ถ์์ data์ request๊ฐ ์ค๊ฒ ๋๋ฉด ํด๋น ๋ฐ์ดํฐ์ partition key(Row key)์ hash ๊ฐ์ ๊ณ์ฐํ์ฌ ํด๋น ๋ฐ์ดํฐ๊ฐ ์ด๋ ๋ ธ๋์ ์ ์ฅ๋์ด ์๋์ง(ํน์ ์ ์ฅํ ๊ฒ์ธ์ง) ์๊ณ ์ ๊ทผํ ์ ์๋ ๊ฒ์ด์ฃ . ๊ทธ๋ฆฌ๊ณ Cassandra๋ ์ด๋ ๊ฒ ๊ณ์ฐ๋ hash์ ๊ฐ์ token์ด๋ผ๊ณ ๋ถ๋ฆ ๋๋ค.
๊ทธ๋ผ ์ด์ partition key๊ฐ ๋ญ์ง, Row key๋ผ๋ ๊ฒ ๋ญ์ง ์์์ผ ํ ํ์๊ฐ ์์ต๋๋ค. ๋์ ์ฐจ์ด๊ฐ ๋ญ๊น์? ์ ์๋ CQL์์ ์ฌ์ฉํ๋ ์ฉ์ด๊ณ ํ์๋ Cassandra Data Layer์์ ์ฌ์ฉ๋๋ ์ฉ์ด์ ๋๋ค. ํ์ง๋ง ์ด๋ ๊ฒ๋ง ๋งํ๋ค๋ฉด ์ ํํ ์ดํด๊ฐ ๊ฐ์ง ์๊ณ ํผ๋์ค๋ฌ์์ง๋๋ค. ๋๊ตฌ๋ ์ง๊ธ ์ธ๊ธํ Row key์ ์์ ๋งํ๋ Table์ ๊ตฌ์ฑ์์์ธ Row์ ๋ญ๊ฐ ๋ค๋ฅธ ๊ฑธ๊น์? ์ฉ์ด์ ํผ๋์ ๋๊ณต ์ง์ง์ด ์ผ์ด๋ฉ๋๋ค. ์ด๋ฅผ ์ ๋ฆฌํ๊ธฐ ์ํด์๋ ์ ์ Cassandra์ History๋ฅผ ํ์ด๋ณผ ํ์๊ฐ ์์ต๋๋ค.
ํ์ฌ Cassandra๋ CQL(Cassandra Query Language)์ ์ฌ์ฉ์ ๊ถ์ฅํ๊ณ ์์ง๋ง CQL์ด ์ฒ์๋ถํฐ ์ ๊ณต๋์๋ ๊ฒ์ ์๋๋๋ค. ์ด๊ธฐ์ Cassandra๋ Thrift protocol์ ์ด์ฉํ client API๋ฅผ ์ ๊ณตํ์๊ณ , ์์ Cassandra์ ์ง์ ์ ๊ทผํด๋ณด๊ณ ์ถ๋ค๋ฉด bin/cassandra-cli ์ ํธ๋ฆฌํฐ๋ฅผ ์ด์ฉํ์ฌ ๋ฐ์ดํฐ๋ฅผ ํ์ธํ ์ ์์์ต๋๋ค. ์ด๋ฌํ ๊ธฐ์กด์ Thrift ๊ธฐ๋ฐ์ api์ cli ์ ํธ๋ฆฌํฐ๋ค์ Cassandra Data layer๋ฅผ ์๋ ๊ทธ๋๋ก ํํํด์ฃผ์์ง๋ง, Thrift๊ฐ ๊ฐ์ง๋ ์ฌ๋ฌ ๊ฐ์ง ํ๊ณ์ ์ ๊ฐ์ด ๊ฐ์ง๊ณ ์์์ฃ . ๋๋ฌธ์ Cassandra 1.2๋ฒ์ ์ดํ์๋ Native Protocol์ ๊ธฐ๋ฐ์ผ๋ก ํ API์ CQL ๋ฌธ๋ฒ์ด ์ถ๊ฐ๋์๊ณ , 3.0 ๋ฒ์ ๋ถํฐ๋ ๊ธฐ์กด์ Thrift ๊ธฐ๋ฐ์ bin/cassandra-cli ์ ํธ๋ฆฌํฐ๋ ์์ Deprecated ๋์ด ์ฌ๋ผ์ก์ต๋๋ค.
๋๊ตฌ๋ ์ด ์๊ธฐ์ Cassandra์๋ ๋ค๋ฅธ ๋ง์ ๋ณํ๊ฐ ๊ฐ์ด ์์์ต๋๋ค. Super Column์ด๋ผ๊ณ ํ๋ Column ์์ Column ํํ๋ฅผ ๊ฐ์ง๋ ์๋ฃ๊ตฌ์กฐ๊ฐ ์์ ์คํ์์ ์ ์ธ๋์ด Collection์ด๋ผ๋ ๊ฒ์ผ๋ก ์๋กญ๊ฒ ๋์ฒด๋์์ผ๋ฉฐ, ๊ธฐ์กด์ Column Family๋ผ๊ณ ๋ถ๋ฆฌ๋ ์๋ฃ๊ตฌ์กฐ๋ Table๋ก ๋ช ์นญ์ด ๋ณ๊ฒฝ๋์์ต๋๋ค. ์ด ๊ณผ์ ์์ CQL์ ์ด๋ ๊ฒ ์๋กญ๊ฒ ๊ตฌ์ฑ๋ Cassandra Data Layer๋ฅผ ์ถ์์ ์ผ๋ก ํํํ๋ ๋ฌธ๋ฒ์ผ๋ก ๊ตฌ์ฑ๋์๊ณ , ๋ฐ๋ผ์ ์ค์ Data Layer์ ์ฉ์ด๋ค๊ณผ CQL์์์ ํํ์ด 1:1๋ก ๋งค์นญ๋์ง ์๊ณ ๋ฌ๋ผ์ง๊ฒ ๋์๋ ๊ฒ์ด์ฃ .
์ด์ฐฝ๊ธฐ Cassandra Data Structure๋ ์์ ๊ทธ๋ฆผ๊ณผ ๊ฐ์ด Keyspace > Column Family > Row > Column(Column Name + Column Value) ํํ๋ก ๊ตฌ์ฑ๋์ด ์์์ต๋๋ค. Keyspace์ Column Family์ ๋ํ ์ ๋ณด๋ ๋ชจ๋ Cassandra node์ memory์ ์ ์ฅ๋๋ฉฐ, ์ค์ ์ ์ ์ ๋ฐ์ดํฐ๋ค์ด ์ ์ฅ๋๋ Row๋ ๊ฐ Row key๋ฅผ ๊ฐ์ง๊ณ ์ด๊ฒ์ hash ๊ฐ์ธ token์ ๊ธฐ์ค์ผ๋ก ๊ฐ ๋ ธ๋์ ๋ถ์ฐ ์ ์ฅ๋์์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ Row์ ์ํ๋ Column๋ค์ Column name์ ๊ธฐ์ค์ผ๋ก ์ ๋ ฌ๋์ด ์ ์ฅ๋ฉ๋๋ค.
์ด๋ฌํ ํํ๋ Cassandra 1.2 ์ ๋ค์ด์ Keyspace > Table > Row > Column(Column Name + Column Value)๋ก ๋ช ์นญ์ด ๋ฐ๋๊ฒ ๋ฉ๋๋ค. ํ์ง๋ง ์ด๋ ํจ๊ป ๋ฑ์ฅํ CQL์ ์ด๋ฅผ ์๋ ๊ทธ๋๋ก ํํํ์ง ์๊ณ , ํ ๋จ๊ณ ์ถ์ํํ์ฌ ํํํฉ๋๋ค.
์ฌ์ ํ ๊ฐ์ ์๋ฏธ๋ก ์ฌ์ฉ๋๋ Keyspace์ Table๊ณผ๋ ๋ค๋ฅด๊ฒ, CQL์์์ Row์ Column์ ์ค์ ๋ฐ์ดํฐ๊ฐ ์ ์ฅ๋๋ ์ง๊ธ๊น์ง ๋ณด์๋ Cassandra Data Layer์์์ Row, Column๊ณผ ๊ทธ ์๋ฏธ๊ฐ ๋ค๋ฆ ๋๋ค. ๊ทธ๋ฆผ์์ ์ ์ ์๋ฏ, CQL์์ Row์ Column์ RDBMS์ Tuple, Attribute์ ์ ์ฌํ๋ค๋ ๊ฒ์ ์ ์ ์์ต๋๋ค. ํ ์ด๋ธ์ ํ๊ณผ ์ด์ธ ๊ฒ์ด์ฃ . ํ์ง๋ง ์ด๋ ๊ฒ ๊ตฌ์ฑ๋ CQL Table์ ์ต์ 1๊ฐ ์ด์์ Column์ primary key๋ผ๋ ๊ฒ์ผ๋ก ์ง์ ํด์ผ ํ๋ฉฐ, Cassandra๋ ์ด๋ ๊ฒ primary key๋ก ์ง์ ๋ column๋ค ์ค์์ partition key๋ก ์ง์ ๋ column์ value๋ฅผ ๊ธฐ์ค์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ๋ถ์ฐํ๊ฒ ๋ฉ๋๋ค.
๋ง์ด ๋งค์ฐ ๋ณต์กํ๊ธฐ ๋๋ฌธ์ bin/cqlsh ์ ํธ๋ฆฌํฐ๋ฅผ ์ด์ฉํ์ฌ ์์ ๋ฅผ ํ๋ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
CREATE TABLE test_keyspace.test_table_ex1 (
code text,
location text,
sequence text,
description text,
PRIMARY KEY (code, location)
);
'test_keyspace' Keyspace์ 'test_table_ex1'์ด๋ผ๋ Table์ ์์ฑํฉ๋๋ค. ์ด๋ 'test_table_ex1'์ด๋ผ๋ Table์ ๊ฐ๊ฐ 'code', 'location', 'sequence', 'description'์ด๋ผ๋ Column๋ค์ ๊ฐ์ง๋ฉฐ ๊ฐ๊ฐ์ ์๋ฃํ์ ๋ชจ๋ text์ ๋๋ค. ๊ทธ๋ฆฌ๊ณ primary key๋ก 'code'์ 'location'์ ์ง์ ํ์๋๋ฐ, ์ด๋ CQL์ ๋ฌธ๋ฒ์ ๋ฐ๋ผ ๊ฐ์ฅ ์ฒซ ๋ฒ์งธ์ 'code'๋ partition key๋ก, ๋ ๋ฒ์งธ์ 'location'์ ์๋์ ์ผ๋ก 'cluster key'๋ผ๋ ๊ฒ์ผ๋ก ์ง์ ๋ฉ๋๋ค. (cluster key๋ Cassandra Data Layer์์ Row ๋ด๋ถ Column๋ค์ ์ ๋ ฌ์ ๋ด๋นํ๋ key๋ก, ์์ธํ ๋ด์ฉ์ ์ข ๋ ๋ค์ ์ค๋ช ํ๊ฒ ์ต๋๋ค.) ์ด๋ ๊ฒ table์ด ์์ฑ๋์๋ค๋ฉด ๋ค์ฏ ๊ฑด์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ ฅํ ํ ๋ฐ์ดํฐ๋ฅผ ํ์ธํด๋ด ๋๋ค.
INSERT INTO test_keyspace.test_table_ex1 (code, location, sequence, description ) VALUES ('N1', 'Seoul', 'first', 'AA');
INSERT INTO test_keyspace.test_table_ex1 (code, location, sequence, description ) VALUES ('N1', 'Gangnam', 'second', 'BB');
INSERT INTO test_keyspace.test_table_ex1 (code, location, sequence, description ) VALUES ('N2', 'Seongnam', 'third', 'CC');
INSERT INTO test_keyspace.test_table_ex1 (code, location, sequence, description ) VALUES ('N2', 'Pangyo', 'fourth', 'DD');
INSERT INTO test_keyspace.test_table_ex1 (code, location, sequence, description ) VALUES ('N2', 'Jungja', 'fifth', 'EE');
SELECT * FROM test_keyspace.test_table_ex1;
๊ทธ๋ ๋ค๋ฉด ์ด Table์ ์ด๋ฒ์ bin/cassandra-cli๋ก ์ถ๋ ฅํด๋ณด๋ฉด ์ด๋ป๊ฒ ๋ ๊น์? ํ์ธํด๋ณด๊ฒ ์ต๋๋ค. (value์ ๊ฐ์ byte๋ก ๋ณํ๋์ด ์ ์ฅ๋๋ฏ๋ก ์๋์ ๊ฐ์ด ์ ์๋ก ํํ๋ฉ๋๋ค.)
use test_keyspace;
list test_table_ex1;
-- Using default limit of 100
-- Using default cell limit of 100
-- -------------------
-- RowKey: N1
-- => (name=Gangnam:, value=, timestamp=1452481808817684)
-- => (name=Gangnam:description, value=4242, timestamp=1452481808817684)
-- => (name=Gangnam:sequence, value=7365636f6e64, timestamp=1452481808817684)
-- => (name=Seoul:, value=, timestamp=1452481808814357)
-- => (name=Seoul:description, value=4141, timestamp=1452481808814357)
-- => (name=Seoul:sequence, value=6669727374, timestamp=1452481808814357)
-- -------------------
-- RowKey: N2
-- => (name=Jungja:, value=, timestamp=1452481808833644)
-- => (name=Jungja:description, value=4545, timestamp=1452481808833644)
-- => (name=Jungja:sequence, value=6669667468, timestamp=1452481808833644)
-- => (name=Pangyo:, value=, timestamp=1452481808829751)
-- => (name=Pangyo:description, value=4444, timestamp=1452481808829751)
-- => (name=Pangyo:sequence, value=666f75727468, timestamp=1452481808829751)
-- => (name=Seongnam:, value=, timestamp=1452481808823137)
-- => (name=Seongnam:description, value=4343, timestamp=1452481808823137)
-- => (name=Seongnam:sequence, value=7468697264, timestamp=1452481808823137)
--
-- 2 Rows Returned.
-- Elapsed time: 67 ms.
์ด๋ value์ ์๋ฌด๊ฒ๋ ์๋ Column๋ค์ ์๋ชป๋ ๋ฐ์ดํฐ๊ฐ ์๋๋ผ, Cassandra๊ฐ CQL๋ก๋ถํฐ ์ ๋ ฅ๋ ๋ฐ์ดํฐ๋ฅผ ๋ด๋ถ์ ์ผ๋ก ๋ณํํ์ฌ ์ฌ์ฉํ๋ ๋ฐ์ดํฐ Column์ด๋ฏ๋ก ์ด ๋ถ๋ถ๋ค์ ์ ์ธํ์ฌ ๋ค์ ์ ๋ฆฌํด๋ณด๋ฉด ์๋์ ๊ฐ์ต๋๋ค.
-- Using default limit of 100
-- Using default cell limit of 100
-- -------------------
-- RowKey: N1
-- => (name=Gangnam:description, value=4242, timestamp=1452481808817684)
-- => (name=Gangnam:sequence, value=7365636f6e64, timestamp=1452481808817684)
-- => (name=Seoul:description, value=4141, timestamp=1452481808814357)
-- => (name=Seoul:sequence, value=6669727374, timestamp=1452481808814357)
-- -------------------
-- RowKey: N2
-- => (name=Jungja:description, value=4545, timestamp=1452481808833644)
-- => (name=Jungja:sequence, value=6669667468, timestamp=1452481808833644)
-- => (name=Pangyo:description, value=4444, timestamp=1452481808829751)
-- => (name=Pangyo:sequence, value=666f75727468, timestamp=1452481808829751)
-- => (name=Seongnam:description, value=4343, timestamp=1452481808823137)
-- => (name=Seongnam:sequence, value=7468697264, timestamp=1452481808823137)
--
-- 2 Rows Returned.
-- Elapsed time: 67 ms.
CQL๊ณผ๋ ๋ฌ๋ฆฌ ๋จ์ง 2๊ฐ์ Row๊ฐ ์๊ณ , ๊ฐ Row๋ง๋ค ์ํด์๋ Column์ ๊ฐ์๊ฐ ๋ค๋ฅธ ๊ฒ์ ์ ์ ์์ต๋๋ค. ์ค์ Cassandra๋ **'N1'๊ณผ 'N2'**๋ฅผ ๊ฐ๊ฐ Hashing ํ์ฌ Token์ ๊ณ์ฐํ๊ณ ์ด Token์ด Cassandra ๋ ธ๋ ์ค์์ ๋ฒ์์ ํด๋นํ๋ ๋ ธ๋๋ฅผ ์ฐพ์ ๋ฐ์ดํฐ๋ฅผ CRUD ํ๋ ๊ฒ์ด์ฃ . ์ด๋ฅผ ๋งจ ์ฒ์ CQL ์ถ๋ ฅ ํ๋ฉด๊ณผ ๋น๊ตํ๊ณ , primary key์ ์กฐํฉ์ ๋ณ๊ฒฝํ์ฌ ๋ค๋ฅธ ์ผ์ด์ค๋ฅผ ์ข ๋ ํ ์คํธํด๋ณธ๋ค๋ฉด ๋ค์๊ณผ ๊ฐ์ ๊ฒฐ๋ก ์ ๋ด๋ฆด ์ ์์ต๋๋ค.
- Cassandra๋ Row Key์ Hash ๊ฐ์ ์ด์ฉํ์ฌ ๋ฐ์ดํฐ๋ฅผ ๋ถ์ฐํ๋ค.
- ์ด๋, Cassandra Data Layer์์์ Row key = CQL partition key์ value์ด๋ค. (๋ณต์์ partition key๋ผ๋ฉด ํด๋น Column value๋ค๊ณผ ":"๋ฌธ์์ ์กฐํฉ์ด๋ค.)
- ๊ทธ๋ฆฌ๊ณ , Cassandra Data Layer์์์ Column Name = CQL cluster key์ Column value์ primary key์ ์ํ์ง ์์ Column Name๋ค ๋ฐ ":" ๋ฌธ์์ ์กฐํฉ์ด๋ค.
cluster key์ ๊ฐ์ด ์์ง ์ค๋ช ์ด ๋ถ์กฑํ ๋ถ๋ถ๋ค์ด ์์ง๋ง CQL์์ ์ฌ์ฉ๋๋ key๋ค์ ๋ํ ์ค๋ช ์ ์ ์ ๋ค์ ํ๋๋ก ํ๊ฒ ์ต๋๋ค.
4. Virtual Node
๋น๋ก ๋ชจ๋ ๋ถ๋ถ์ ๋ํด์ ํ์ธํ์ง๋ ์์์ง๋ง, ์ง๊ธ๊น์ง์ ๋ด์ฉ์ ํตํ์ฌ ์ผ๋จ์ Cassandra ๊ฐ ์ด๋ป๊ฒ ๋ฐ์ดํฐ๋ฅผ ๋ถ์ฐํ๋ ๊ฑด์ง ๋๋ต ์ ๋ฆฌํ์์ต๋๋ค. ํ์ง๋ง Cassandra๋ฅผ ์กฐ์ฌํ๋ค ๋ณด๋ฉด ๋๋ค์ ์ฌ๋์ ํผ๋์ค๋ฝ๊ฒ ๋ง๋๋ ์ฉ์ด๋ค์ด ํ์ด๋์ค๊ฒ ๋๋๋ฐ, ๋ฐ๋ก initial token๊ณผ num tokens, virtual node๊ฐ ์ฃผ์ธ๊ณต๋ค์ ๋๋ค. ์์ํ์๊ฒ ์ง๋ง ์ญ์ ์ด๊ฒ๋ค๋ Cassandra๊ฐ ๋ช ์ฐจ๋ก์ ๋ฒ์ ์ ์ ํ๋ ๊ณผ์ ์์ ์๊ธด ์ฉ์ด๋ค์ ๋๋ค.
์์ ๋ด์ฉ๋ค์ ๋ค์ ๋ณต๊ธฐํด๋ด ์๋ค. ์ฌ์ฉ์๋ Cassandra์ Data๋ฅผ CRUD ํฉ๋๋ค. ์ด๋, ํด๋น ๋ฐ์ดํฐ์์ Partition Key๋ก ์ง์ ๋ Column๋ค์ Value๋ค์ ์กฐํฉ์ด Row Key๊ฐ ๋๋ ๊ฒ์ด๊ณ ์ด Row Key๋ฅผ Hashing ํ์ฌ token์ ๊ณ์ฐํ ๋ค, ํด๋น token์ ๋ฒ์์ ์ํ Node๋ฅผ ์ฐพ์ CRUD ํฉ๋๋ค. ๊ทธ๋ ๋ค๋ฉด ์ฌ๊ธฐ์ ์ ์ ์กฐ๊ฑด์ด ํ๋ ํ์ํ๊ฒ ๋ฉ๋๋ค. ๋ฌด์๋ณด๋ค๋ ๊ฐ์ฅ ๋จผ์ , ๊ฐ ๋ ธ๋ ๋ณ token์ ๋ฒ์๊ฐ ํ ๋น๋์ด ์์ด์ผ ํ๋ ๊ฒ์ด์ฃ .
์ด๋ฏธ ์ค๋ช ๋๋ ธ๋ฏ์ด, Cassandra๋ Ring ๊ตฌ์กฐ๋ก ์ด๋ฃจ์ด์ ธ ์์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ Cassandra์ ์ด์ฐฝ๊ธฐ์๋ ์ง์ ์์์ ์ด๋ ์คํฌ๋ฆฝํธ๋ฅผ ์ด์ฉํด Hash ๊ฐ์ ๋ฒ์๋ฅผ ๊ตฌํ์ฌ Cassandra์ ๊ฐ ๋ ธ๋๋ณ conf/cassandra.yaml์ "initial_token"์ด๋ผ๋ ์ต์ ์ ํด๋น Hash ๊ฐ์ ์ง์ ํด์ฃผ์ด์ผ ํ์ต๋๋ค. ์ฆ, Cassandra๊ฐ ๊ตฌ๋ ์ initial token์ ์ง์ ๋ ๊ฐ์ ์ฝ์ด ์์ ์ด ๋ด๋นํ๋ hash ๋ฒ์๋ฅผ ๊ณ์ฐํ์์ต๋๋ค. ์ด๋ ๋ง์ฝ ํน์ ๋ ธ๋๋ฅผ ์ถ๊ฐ, ์ ๊ฑฐํด์ผ ํ ๋๋ ํน์ ๋ ธ๋์ ๋ฐ์ดํฐ๊ฐ ๋ชฐ๋ฆฌ์ง ์๋๋ก ์์์ ์ผ๋ก initial token์ ๋ค์ ๊ณ์ฐํ์ฌ conf/cassandra.yaml์ ๊ฐฑ์ ํ ๋ค Cassandra๋ฅผ ๊ตฌ๋ํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ bin/nodetool ์ ํธ๋ฆฌํฐ์ move, remove, decommission, cleanup๊ณผ ๊ฐ์ ๋ช ๋ น์ด๋ฅผ ํตํด ์์์ ์ผ๋ก ๊ธฐ์กด ๋ฐ์ดํฐ๋ค์ ๋ฆฌ๋ฐธ๋ฐ์ฑ์ ํ์์ฃ . ๊ทธ๋ฆฌ๊ณ Cassandra 1.2๋ถํฐ virtual node๋ผ๋ ๊ธฐ๋ฅ์ด ์ถ๊ฐ๋์์ต๋๋ค.
virtual node๋ ๋ค๋ฆ์ด ์๋๋ผ ํ๋์ ์ค์ Cassandra ๋ ธ๋ ์์ ๊ฐ์ ๋ ธ๋๋ฅผ ์ฌ๋ฌ ๋ ๋๊ณ , ์์ฃผ ์๊ฒ ๋๋์ด์ง token ๋ฒ์๋ฅผ ๊ฐ์๋ ธ๋๋ค์๊ฒ ํ ๋นํ์ฌ ๋ฐ์ดํฐ๋ฅผ ๋ถ์ฐํ๋ค๋ ๊ฐ๋ ์ ๋๋ค. virtual node์ ์ด์ ์ ์ด๋ฌํ ๋ค์์ ๊ฐ์ ๋ ธ๋๋ค์ ํตํ์ฌ ์ข ๋ ๋ฐ์ดํฐ๋ฅผ ๊ท ์ผํ๊ฒ ๋ถ์ฐํ๊ธฐ ์ฝ๊ณ , ๋ฐ์ดํฐ๊ฐ ์ด๋ฏธ ์ฌ๋ฌ ๋์ ๋ ธ๋์ ๋ถ์ฐ๋์ด ์์ผ๋ฏ๋ก ๋ ธ๋์ ์ถ๊ฐ, ์ ๊ฑฐ์ ๋ฐ์ดํฐ์ ์ด๋, ๋ณต์ , ๋ฆฌ๋ฐธ๋ฐ์ฑ์ ๋์ ์ฑ๋ฅ ํฅ์์ ๊ฐ์ ธ๋ค ์ค๋๋ค. ๋ฐ๋ผ์ ํ๋์ ๋ ธ๋์ ๋ช ๋์ ๊ฐ์ ๋ ธ๋๋ฅผ ์ด์ํ ๊ฒ์ธ์ง์ ๋ํ ์ต์ ์ด ๋ฐ๋ก conf/cassandra.yaml์ "num_tokens" ํญ๋ชฉ์ธ ๊ฒ์ด์ฃ . ๊ทธ๋ฆฌ๊ณ ์ด๋ ๊ฒ virtual node๋ฅผ ์ฌ์ฉํ ๊ฒฝ์ฐ ๋ ธ๋ ์ถ๊ฐ ์ ๊ฑฐ์ ๋ฐ๋ฅธ token์ ๋งค๋ฒ ์์์ ์ผ๋ก ์์ฑํ์ฌ ์ต์ ์ ๋ฃ์ด์ค ํ์๊ฐ ์์ด, Ring์ ์ํ ๋ชจ๋ node ๋ค์ด ์์์ gossip protocol์ ํตํด ์ฅ๋์ฅ๋ ์๋ ผํ์ฌ token ๋ฒ์๋ฅผ ๊ฒฐ์ ํ๊ณ ๋ฆฌ๋ฐธ๋ฐ์ฑ๊น์ง ์ฒ๋ฆฌํด์ค๋๋ค. ํธ๋ฆฌํ๊ณ ๊ฐ๋ ฅํ ๊ธฐ๋ฅ์ธ ์ ์ ๋๋ค.
5. CQL key ์ฉ์ด ์ ๋ฆฌ.
์์ ๋งํ ์ ์ด ์๋ฏ, ์ฌ์ค CQL์์ SQL๊ณผ ๊ฑฐ์ ๊ทธ ํํ๊ฐ ์ ์ฌํ๊ธฐ๋ ํ์ฌ ์ฌ์ฉ์ ํฐ ์ด๋ ค์์ด ์์ง๋ ์์ต๋๋ค. ๋๊ตฌ๋ ์ด ๋ฌธ์์์ ๋ชจ๋ CQL์ ๋ฌธ๋ฒ์ ๋ค๋ฃจ๋ ๊ฒ์ ๋ค์ ์๊ฐ์ , ๊ณต๊ฐ์ ๋ญ๋น์ธ ์ธก๋ฉด์ด ์๊ธฐ ๋๋ฌธ์ CQL์ ์ ๋ถ๋ฅผ ์์๋ณด๊ธฐ๋ณด๋ค๋, Cassandra์ ์ ํฉํ ๋ฐ์ดํฐ ๋ชจ๋ธ๋ง์ ๊ตฌํํ๊ธฐ ์ํ CQL์ ๋ฑ์ฅํ๋ ๊ฐ์ข key๋ค์ ์๋ฏธ๋ฅผ ๊ฐ๋จํ ์ ๋ฆฌํ๊ฒ ์ต๋๋ค. (์ฌ์ค ์ฉ์ด์ ํผ๋์ด ์ฌ๊ธฐ์์ ๊ฐ์ฅ ๋ง์ด ์ผ์ด๋๊ธฐ ๋๋ฌธ์ด๊ธฐ๋ ํฉ๋๋ค.)
partition key
- partition key๋ CQL ๋ฌธ๋ฒ์์ Cassandra์ data๋ฅผ ๋ถ์ฐ ์ ์ฅํ๊ธฐ ์ํ uniqueํ key์ ๋๋ค.
- partition key๋ ํน์ table์ ๊ตฌ์ฑํ ๋ ๋ฐ๋์ 1๊ฐ ์ด์์ด ์ง์ ๋์ด์ผ ํ๋ฉฐ, ์ฌ๋ฌ ๊ฐ ์ง์ ๋ ์๋ ์์ต๋๋ค.
- partition key๊ฐ ๋จ 1๊ฐ์ผ ๊ฒฝ์ฐ, ํด๋น partition key๋ก ์ง์ ๋ CQL Column์ value๊ฐ ์ค์ Cassandra Data Layer์ Row key๋ก ์ ์ฅ๋ฉ๋๋ค.
- partition key๊ฐ ์ฌ๋ฌ ๊ฐ์ผ ๊ฒฝ์ฐ, ๊ฐ partition key๋ก ์ง์ ๋ CQL Column๋ค์ value๋ค์ ":"๋ฌธ์์ ํจ๊ป ์กฐํฉํ ๊ฐ๋ค์ด ์ค์ Cassandra Data Layer์ Row key๋ก ์ ์ฅ๋ฉ๋๋ค.
cluster key
- ์์๋ค์ํผ Cassandra Data Layer์์ Row์ ์ํ ๋ชจ๋ Column๋ค์ ํญ์ ์ ๋ ฌ๋ ์ํ๋ก ์ ์ฅ๋ฉ๋๋ค.
- ๋ฐ๋ผ์ cluster key๋ ์ด๋ฌํ ์ ๋ ฌ์ ๋ํ ๊ธฐ์ค ์ญํ ์ ๋ด๋นํฉ๋๋ค.
- CQL์์ cluster key๋ก ์ง์ ๋ CQL Column๋ค์ value๋ค์ ๋๋จธ์ง Column๋ค์ name ๋ฐ ":" ๋ฌธ์์ ํจ๊ป ์กฐํฉ๋์ด, ์ด ๊ฐ์ด ์ค์ Cassandra Data Layer์ Column Name์ผ๋ก ์ ์ฅ๋ฉ๋๋ค. ๋ง์ฝ cluster key๊ฐ ์ ํ ์๋ ๊ฒฝ์ฐ์, CQL Column์ name์ด ๊ทธ๋๋ก Cassandra Data Layer์ Column Name์ด ๋ฉ๋๋ค.
primary key
- primary key๋ CQL table์์์ ๊ฐ row๋ฅผ ๊ฐ์ unique ํ๊ฒ ๊ฒฐ์ ํด์ฃผ๋ ๊ธฐ์ค ์ญํ ์ ๋ด๋นํฉ๋๋ค.
- primary key๋ ์ต์ 1๊ฐ ์ด์์ partition key์ 0๊ฐ ์ด์์ cluster key๋ก ๊ตฌ์ฑ๋ฉ๋๋ค.
composite key(=compound key)
- 1๊ฐ ์ด์์ CQL Column๋ค๋ก ์ด๋ฃจ์ด์ง primary key๋ฅผ composite key ํน์ compound key๋ผ๊ณ ๋ถ๋ฆ ๋๋ค.
composite partition key
- composite partition key๋ 2๊ฐ ์ด์์ ๋ค์์ CQL Column์ผ๋ก ์ด๋ฃจ์ด์ง partition key๋ฅผ ์๋ฏธํฉ๋๋ค.
6. 1ํธ์ ๋ง์น๋ฉฐ.
์ต๋ํ ๊ฐ๋จํ๊ฒ ์ฐ๋ ค๊ณ ํ๋๋ฐ, ์ญ์ ์ฝ์ง ์์์ต๋๋ค. ์ด๋ป๊ฒ๋ ๊ฐ์ถ๋ ค์ ํํธ์ผ๋ก ๋ง๋ค์ด ๋ณด๊ณ ์ ํ์ง๋ง ์๋ฌด๋๋ ํ๋ค ๊ฒ ๊ฐ์ 2ํธ์ผ๋ก ๋๋์ด ๋จ์ ๋ด์ฉ๋ค์ ๋ค์ ํธ์์ ๋ค๋ฃจ์ด์ผ ํ ๊ฒ ๊ฐ์ต๋๋ค. 2ํธ์์๋ 1ํธ์ ๋ํ ์ฝ๊ฐ์ ์ถ๊ฐ ๋ด์ฉ ๋ฐ Cassandra์ ๋ฐ์ดํฐ๋ฅผ ์ฝ๊ณ ์ธ ๋ ์ผ์ด๋๋ ์ ์ฐจ์ Cassandra์์ ์ ๊ณตํ๋ ๊ธฐ๋ฅ๋ค, Cassandra์์ ์์ฃผ ์ฌ์ฉ๋๊ฑฐ๋ ํน์ ํผํด์ผํ ํจํด์ ๋ํ ์ด์ผ๊ธฐ ๋ฑ์ ์ ๋ฆฌํ๊ฒ ์ต๋๋ค.
๊ฐ์ฌํฉ๋๋ค.