Skip to content

Commit 522fd50

Browse files
committed
Add schema for cassandra v4.0.
We don't need to add v003tov004.sh because the change (removal of dclocal_read_repair_chance config) is in table metadata which gets handled seemlessly within cassandra upgrade when users upgrade their cassandra cluster from v3.11 to v4.0. Refactor cassandra integration tests to run on both cassandra v3.11 and v4.0. Signed-off-by: Ashmita Bohara <ashmita.bohara152@gmail.com>
1 parent a5ced10 commit 522fd50

File tree

3 files changed

+227
-20
lines changed

3 files changed

+227
-20
lines changed

.github/workflows/ci-cassandra.yml

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,16 @@ on:
99
jobs:
1010
cassandra:
1111
runs-on: ubuntu-latest
12+
strategy:
13+
matrix:
14+
version:
15+
- image: cassandra
16+
tag: 3.11
17+
schema: v001 v002 v003
18+
- image: cassandra
19+
tag: 4.0
20+
schema: v004 v004 v004
21+
name: ${{ matrix.version.image }} ${{ matrix.version.tag }}
1222
steps:
1323
- uses: actions/checkout@v2.3.4
1424

@@ -17,4 +27,20 @@ jobs:
1727
go-version: ^1.17
1828

1929
- name: Run cassandra integration tests
20-
run: bash scripts/cassandra-integration-test.sh
30+
run: bash scripts/cassandra-integration-test.sh ${{ matrix.version.schema }}
31+
services:
32+
cassandra1:
33+
image: ${{ matrix.version.image }}:${{ matrix.version.tag }}
34+
ports:
35+
- 9042:9042
36+
- 9160:9160
37+
cassandra2:
38+
image: ${{ matrix.version.image }}:${{ matrix.version.tag }}
39+
ports:
40+
- 9043:9042
41+
- 9161:9160
42+
cassandra3:
43+
image: ${{ matrix.version.image }}:${{ matrix.version.tag }}
44+
ports:
45+
- 9044:9042
46+
- 9162:9160
Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
--
2+
-- Creates Cassandra keyspace with tables for traces and dependencies.
3+
--
4+
-- Required parameters:
5+
--
6+
-- keyspace
7+
-- name of the keyspace
8+
-- replication
9+
-- replication strategy for the keyspace, such as
10+
-- for prod environments
11+
-- {'class': 'NetworkTopologyStrategy', '$datacenter': '${replication_factor}' }
12+
-- for test environments
13+
-- {'class': 'SimpleStrategy', 'replication_factor': '1'}
14+
-- trace_ttl
15+
-- default time to live for trace data, in seconds
16+
-- dependencies_ttl
17+
-- default time to live for dependencies data, in seconds (0 for no TTL)
18+
--
19+
-- Non-configurable settings:
20+
-- gc_grace_seconds is non-zero, see: http://www.uberobert.com/cassandra_gc_grace_disables_hinted_handoff/
21+
-- For TTL of 2 days, compaction window is 1 hour, rule of thumb here: http://thelastpickle.com/blog/2016/12/08/TWCS-part1.html
22+
23+
CREATE KEYSPACE IF NOT EXISTS ${keyspace} WITH replication = ${replication};
24+
25+
CREATE TYPE IF NOT EXISTS ${keyspace}.keyvalue (
26+
key text,
27+
value_type text,
28+
value_string text,
29+
value_bool boolean,
30+
value_long bigint,
31+
value_double double,
32+
value_binary blob,
33+
);
34+
35+
CREATE TYPE IF NOT EXISTS ${keyspace}.log (
36+
ts bigint, // microseconds since epoch
37+
fields list<frozen<keyvalue>>,
38+
);
39+
40+
CREATE TYPE IF NOT EXISTS ${keyspace}.span_ref (
41+
ref_type text,
42+
trace_id blob,
43+
span_id bigint,
44+
);
45+
46+
CREATE TYPE IF NOT EXISTS ${keyspace}.process (
47+
service_name text,
48+
tags list<frozen<keyvalue>>,
49+
);
50+
51+
-- Notice we have span_hash. This exists only for zipkin backwards compat. Zipkin allows spans with the same ID.
52+
-- Note: Cassandra re-orders non-PK columns alphabetically, so the table looks differently in CQLSH "describe table".
53+
-- start_time is bigint instead of timestamp as we require microsecond precision
54+
CREATE TABLE IF NOT EXISTS ${keyspace}.traces (
55+
trace_id blob,
56+
span_id bigint,
57+
span_hash bigint,
58+
parent_id bigint,
59+
operation_name text,
60+
flags int,
61+
start_time bigint, // microseconds since epoch
62+
duration bigint, // microseconds
63+
tags list<frozen<keyvalue>>,
64+
logs list<frozen<log>>,
65+
refs list<frozen<span_ref>>,
66+
process frozen<process>,
67+
PRIMARY KEY (trace_id, span_id, span_hash)
68+
)
69+
WITH compaction = {
70+
'compaction_window_size': '1',
71+
'compaction_window_unit': 'HOURS',
72+
'class': 'org.apache.cassandra.db.compaction.TimeWindowCompactionStrategy'
73+
}
74+
AND default_time_to_live = ${trace_ttl}
75+
AND speculative_retry = 'NONE'
76+
AND gc_grace_seconds = 10800; -- 3 hours of downtime acceptable on nodes
77+
78+
CREATE TABLE IF NOT EXISTS ${keyspace}.service_names (
79+
service_name text,
80+
PRIMARY KEY (service_name)
81+
)
82+
WITH compaction = {
83+
'min_threshold': '4',
84+
'max_threshold': '32',
85+
'class': 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'
86+
}
87+
AND default_time_to_live = ${trace_ttl}
88+
AND speculative_retry = 'NONE'
89+
AND gc_grace_seconds = 10800; -- 3 hours of downtime acceptable on nodes
90+
91+
CREATE TABLE IF NOT EXISTS ${keyspace}.operation_names_v2 (
92+
service_name text,
93+
span_kind text,
94+
operation_name text,
95+
PRIMARY KEY ((service_name), span_kind, operation_name)
96+
)
97+
WITH compaction = {
98+
'min_threshold': '4',
99+
'max_threshold': '32',
100+
'class': 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'
101+
}
102+
AND default_time_to_live = ${trace_ttl}
103+
AND speculative_retry = 'NONE'
104+
AND gc_grace_seconds = 10800; -- 3 hours of downtime acceptable on nodes
105+
106+
-- index of trace IDs by service + operation names, sorted by span start_time.
107+
CREATE TABLE IF NOT EXISTS ${keyspace}.service_operation_index (
108+
service_name text,
109+
operation_name text,
110+
start_time bigint, // microseconds since epoch
111+
trace_id blob,
112+
PRIMARY KEY ((service_name, operation_name), start_time)
113+
) WITH CLUSTERING ORDER BY (start_time DESC)
114+
AND compaction = {
115+
'compaction_window_size': '1',
116+
'compaction_window_unit': 'HOURS',
117+
'class': 'org.apache.cassandra.db.compaction.TimeWindowCompactionStrategy'
118+
}
119+
AND default_time_to_live = ${trace_ttl}
120+
AND speculative_retry = 'NONE'
121+
AND gc_grace_seconds = 10800; -- 3 hours of downtime acceptable on nodes
122+
123+
CREATE TABLE IF NOT EXISTS ${keyspace}.service_name_index (
124+
service_name text,
125+
bucket int,
126+
start_time bigint, // microseconds since epoch
127+
trace_id blob,
128+
PRIMARY KEY ((service_name, bucket), start_time)
129+
) WITH CLUSTERING ORDER BY (start_time DESC)
130+
AND compaction = {
131+
'compaction_window_size': '1',
132+
'compaction_window_unit': 'HOURS',
133+
'class': 'org.apache.cassandra.db.compaction.TimeWindowCompactionStrategy'
134+
}
135+
AND default_time_to_live = ${trace_ttl}
136+
AND speculative_retry = 'NONE'
137+
AND gc_grace_seconds = 10800; -- 3 hours of downtime acceptable on nodes
138+
139+
CREATE TABLE IF NOT EXISTS ${keyspace}.duration_index (
140+
service_name text, // service name
141+
operation_name text, // operation name, or blank for queries without span name
142+
bucket timestamp, // time bucket, - the start_time of the given span rounded to an hour
143+
duration bigint, // span duration, in microseconds
144+
start_time bigint, // microseconds since epoch
145+
trace_id blob,
146+
PRIMARY KEY ((service_name, operation_name, bucket), duration, start_time, trace_id)
147+
) WITH CLUSTERING ORDER BY (duration DESC, start_time DESC)
148+
AND compaction = {
149+
'compaction_window_size': '1',
150+
'compaction_window_unit': 'HOURS',
151+
'class': 'org.apache.cassandra.db.compaction.TimeWindowCompactionStrategy'
152+
}
153+
AND default_time_to_live = ${trace_ttl}
154+
AND speculative_retry = 'NONE'
155+
AND gc_grace_seconds = 10800; -- 3 hours of downtime acceptable on nodes
156+
157+
-- a bucketing strategy may have to be added for tag queries
158+
-- we can make this table even better by adding a timestamp to it
159+
CREATE TABLE IF NOT EXISTS ${keyspace}.tag_index (
160+
service_name text,
161+
tag_key text,
162+
tag_value text,
163+
start_time bigint, // microseconds since epoch
164+
trace_id blob,
165+
span_id bigint,
166+
PRIMARY KEY ((service_name, tag_key, tag_value), start_time, trace_id, span_id)
167+
)
168+
WITH CLUSTERING ORDER BY (start_time DESC)
169+
AND compaction = {
170+
'compaction_window_size': '1',
171+
'compaction_window_unit': 'HOURS',
172+
'class': 'org.apache.cassandra.db.compaction.TimeWindowCompactionStrategy'
173+
}
174+
AND default_time_to_live = ${trace_ttl}
175+
AND speculative_retry = 'NONE'
176+
AND gc_grace_seconds = 10800; -- 3 hours of downtime acceptable on nodes
177+
178+
CREATE TYPE IF NOT EXISTS ${keyspace}.dependency (
179+
parent text,
180+
child text,
181+
call_count bigint,
182+
source text,
183+
);
184+
185+
-- compaction strategy is intentionally different as compared to other tables due to the size of dependencies data
186+
CREATE TABLE IF NOT EXISTS ${keyspace}.dependencies_v2 (
187+
ts_bucket timestamp,
188+
ts timestamp,
189+
dependencies list<frozen<dependency>>,
190+
PRIMARY KEY (ts_bucket, ts)
191+
) WITH CLUSTERING ORDER BY (ts DESC)
192+
AND compaction = {
193+
'min_threshold': '4',
194+
'max_threshold': '32',
195+
'class': 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'
196+
}
197+
AND default_time_to_live = ${dependencies_ttl};

scripts/cassandra-integration-test.sh

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,13 @@
22

33
set -ex
44

5-
# Clean up before starting.
6-
docker rm -f cassandra || true
7-
docker rm -f cassandra2 || true
8-
docker network rm integration_test || true
9-
10-
# Create a network so that the schema container can communicate with the cassandra containers.
11-
docker network create integration_test
12-
13-
# Start cassandra containers whose ports are exposed to localhost to facilitate testing.
14-
docker run -d --name cassandra --network integration_test -p 9042:9042 -p 9160:9160 cassandra:3.9
15-
docker run -d --name cassandra2 --network integration_test -p 9043:9042 -p 9161:9160 cassandra:3.9
16-
175
# Build the schema container and run it rather than using the existing container in Docker Hub since that
186
# requires this current build to succeed before this test can use it; chicken and egg problem.
197
docker build -t jaeger-cassandra-schema-integration-test plugin/storage/cassandra/
20-
docker run --network integration_test -e CQLSH_HOST=cassandra -e TEMPLATE=/cassandra-schema/v001.cql.tmpl jaeger-cassandra-schema-integration-test
21-
docker run --network integration_test -e CQLSH_HOST=cassandra2 -e TEMPLATE=/cassandra-schema/v002.cql.tmpl jaeger-cassandra-schema-integration-test
8+
docker run -e CQLSH_HOST=localhost -e CQLSH_PORT=9042 -e TEMPLATE=/cassandra-schema/$1.cql.tmpl --network=host jaeger-cassandra-schema-integration-test
9+
docker run -e CQLSH_HOST=localhost -e CQLSH_PORT=9043 -e TEMPLATE=/cassandra-schema/$2.cql.tmpl --network=host jaeger-cassandra-schema-integration-test
10+
docker run -e CQLSH_HOST=localhost -e CQLSH_PORT=9044 -e TEMPLATE=/cassandra-schema/$3.cql.tmpl --network=host jaeger-cassandra-schema-integration-test
2211

2312
# Run the test.
2413
export STORAGE=cassandra
2514
make storage-integration-test
26-
27-
# Tear down after.
28-
docker rm -f cassandra
29-
docker rm -f cassandra2
30-
docker network rm integration_test

0 commit comments

Comments
 (0)