Skip to content

Commit

Permalink
configure num_tokens [K8SSAND-923] (k8ssandra#152)
Browse files Browse the repository at this point in the history
* configure num_tokens

* mark the field optional

* clean up test

* additional test cleanup
  • Loading branch information
jsanda authored Sep 25, 2021
1 parent 7ff6719 commit 608eb39
Show file tree
Hide file tree
Showing 7 changed files with 156 additions and 55 deletions.
6 changes: 6 additions & 0 deletions api/v1alpha1/k8ssandracluster_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,12 @@ type CassandraYaml struct {
//
//PermissionValidityMillis *int64 `json:"permissions_validity_in_ms,omitempty"`

// +optional
NumTokens *int `json:"num_tokens,omitempty"`

// +optional
AllocateTokensForLocalReplicationFactor *int `json:"allocate_tokens_for_local_replication_factor,omitempty"`

// +optional
ConcurrentReads *int `json:"concurrent_reads,omitempty"`

Expand Down
10 changes: 10 additions & 0 deletions api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions config/crd/bases/k8ssandra.io_k8ssandraclusters.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ spec:
properties:
cassandraYaml:
properties:
allocate_tokens_for_local_replication_factor:
type: integer
auto_snapshot:
type: boolean
commitlog_segment_size_in_mb:
Expand All @@ -76,6 +78,8 @@ spec:
type: integer
memtable_flush_writers:
type: integer
num_tokens:
type: integer
prepared_statements_cache_size_mb:
type: integer
row_cache_size_in_mb:
Expand Down Expand Up @@ -120,6 +124,8 @@ spec:
properties:
cassandraYaml:
properties:
allocate_tokens_for_local_replication_factor:
type: integer
auto_snapshot:
type: boolean
commitlog_segment_size_in_mb:
Expand All @@ -142,6 +148,8 @@ spec:
type: integer
memtable_flush_writers:
type: integer
num_tokens:
type: integer
prepared_statements_cache_size_mb:
type: integer
row_cache_size_in_mb:
Expand Down
17 changes: 16 additions & 1 deletion pkg/cassandra/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,19 @@ func (c config) MarshalJSON() ([]byte, error) {
c.StartRpc = nil
c.ThriftPreparedStatementCacheSizeMb = nil
}

// Even though we default to Cassandra's stock defaults for num_tokens, we need to
// explicitly set it because the config builder defaults to num_tokens: 1
if c.NumTokens == nil {
if isCassandra4(c.cassandraVersion) {
numTokens := 16
c.NumTokens = &numTokens
} else {
numTokens := 256
c.NumTokens = &numTokens
}
}

config["cassandra-yaml"] = c.CassandraYaml
}

Expand All @@ -65,7 +78,9 @@ func (c config) MarshalJSON() ([]byte, error) {
func newConfig(apiConfig *api.CassandraConfig, cassandraVersion string) config {
config := config{cassandraVersion: cassandraVersion}

if apiConfig.CassandraYaml != nil {
if apiConfig.CassandraYaml == nil {
config.CassandraYaml = &api.CassandraYaml{}
} else {
config.CassandraYaml = apiConfig.CassandraYaml
}

Expand Down
150 changes: 106 additions & 44 deletions pkg/cassandra/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ package cassandra
import (
"github.com/Jeffail/gabs"
api "github.com/k8ssandra/k8ssandra-operator/api/v1alpha1"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"k8s.io/apimachinery/pkg/api/resource"
"reflect"
"testing"
)

Expand Down Expand Up @@ -106,10 +107,10 @@ func TestApplySystemReplication(t *testing.T) {
}

for _, tc := range tests {
ApplySystemReplication(tc.dcConfig, tc.replication)
if !reflect.DeepEqual(tc.want, tc.dcConfig) {
t.Errorf("%s - expected: %+v, got: %+v", tc.name, *tc.want, *tc.dcConfig)
}
t.Run(tc.name, func(t *testing.T) {
ApplySystemReplication(tc.dcConfig, tc.replication)
require.Equal(t, tc.want, tc.dcConfig)
})
}
}

Expand All @@ -126,8 +127,8 @@ func TestCreateJsonConfig(t *testing.T) {

tests := []test{
{
name: "concurrent_reads, concurrent_writes, concurrent_counter_writes",
cassandraVersion: "4.0",
name: "[4.0.0] concurrent_reads, concurrent_writes, concurrent_counter_writes",
cassandraVersion: "4.0.0",
config: &api.CassandraConfig{
CassandraYaml: &api.CassandraYaml{
ConcurrentReads: intPtr(8),
Expand All @@ -137,30 +138,52 @@ func TestCreateJsonConfig(t *testing.T) {
},
want: `{
"cassandra-yaml": {
"num_tokens": 16,
"concurrent_reads": 8,
"concurrent_writes": 16,
"concurrent_counter_writes": 4
}
}`,
},
{
name: "heap size - Cassandra 4.0",
cassandraVersion: "4.0",
name: "[3.11.11] heap size",
cassandraVersion: "3.11.11",
config: &api.CassandraConfig{
JvmOptions: &api.JvmOptions{
HeapSize: &heapSize,
},
},
want: `{
"cassandra-yaml": {
"num_tokens": 256
},
"jvm-options": {
"initial_heap_size": 1073741824,
"max_heap_size": 1073741824
}
}`,
},
{
name: "[4.0.0] heap size",
cassandraVersion: "4.0.0",
config: &api.CassandraConfig{
JvmOptions: &api.JvmOptions{
HeapSize: &heapSize,
},
},
want: `{
"cassandra-yaml": {
"num_tokens": 16
},
"jvm-server-options": {
"initial_heap_size": 1073741824,
"max_heap_size": 1073741824
}
}`,
},
{
name: "concurrent_reads and concurrent_writes with system replication",
cassandraVersion: "4.0",
name: "[4.0.0] concurrent_reads and concurrent_writes with system replication",
cassandraVersion: "4.0.0",
config: &api.CassandraConfig{
CassandraYaml: &api.CassandraYaml{
ConcurrentReads: intPtr(8),
Expand All @@ -175,6 +198,7 @@ func TestCreateJsonConfig(t *testing.T) {
},
want: `{
"cassandra-yaml": {
"num_tokens": 16,
"concurrent_reads": 8,
"concurrent_writes": 16
},
Expand All @@ -187,8 +211,8 @@ func TestCreateJsonConfig(t *testing.T) {
}`,
},
{
name: "auto_snapshot, memtable_flush_writers, commitlog_segment_size_in_mb",
cassandraVersion: "4.0",
name: "[4.0.0] auto_snapshot, memtable_flush_writers, commitlog_segment_size_in_mb",
cassandraVersion: "4.0.0",
config: &api.CassandraConfig{
CassandraYaml: &api.CassandraYaml{
AutoSnapshot: boolPtr(true),
Expand All @@ -198,15 +222,16 @@ func TestCreateJsonConfig(t *testing.T) {
},
want: `{
"cassandra-yaml": {
"num_tokens": 16,
"auto_snapshot": true,
"memtable_flush_writers": 10,
"commitlog_segment_size_in_mb": 8192
}
}`,
},
{
name: "concurrent_compactors, compaction_throughput_mb_per_sec, sstable_preemptive_open_interval_in_mb",
cassandraVersion: "4.0",
name: "[4.0.0] concurrent_compactors, compaction_throughput_mb_per_sec, sstable_preemptive_open_interval_in_mb",
cassandraVersion: "4.0.0",
config: &api.CassandraConfig{
CassandraYaml: &api.CassandraYaml{
ConcurrentCompactors: intPtr(4),
Expand All @@ -216,15 +241,16 @@ func TestCreateJsonConfig(t *testing.T) {
},
want: `{
"cassandra-yaml": {
"num_tokens": 16,
"concurrent_compactors": 4,
"compaction_throughput_mb_per_sec": 64,
"sstable_preemptive_open_interval_in_mb": 0
}
}`,
},
{
name: "key_cache_size_in_mb, counter_cache_size_in_mb, prepared_statements_cache_size_mb, slow_query_log_timeout_in_ms",
cassandraVersion: "4.0",
name: "[4.0.0] key_cache_size_in_mb, counter_cache_size_in_mb, prepared_statements_cache_size_mb, slow_query_log_timeout_in_ms",
cassandraVersion: "4.0.0",
config: &api.CassandraConfig{
CassandraYaml: &api.CassandraYaml{
KeyCacheSizeMb: intPtr(100),
Expand All @@ -235,6 +261,7 @@ func TestCreateJsonConfig(t *testing.T) {
},
want: `{
"cassandra-yaml": {
"num_tokens": 16,
"key_cache_size_in_mb": 100,
"counter_cache_size_in_mb": 50,
"prepared_statements_cache_size_mb": 180,
Expand All @@ -243,8 +270,8 @@ func TestCreateJsonConfig(t *testing.T) {
}`,
},
{
name: "file_cache_size_in_mb, row_cache_size_in_mb",
cassandraVersion: "4.0",
name: "[4.0.0] file_cache_size_in_mb, row_cache_size_in_mb",
cassandraVersion: "4.0.0",
config: &api.CassandraConfig{
CassandraYaml: &api.CassandraYaml{
FileCacheSizeMb: intPtr(500),
Expand All @@ -253,6 +280,7 @@ func TestCreateJsonConfig(t *testing.T) {
},
want: `{
"cassandra-yaml": {
"num_tokens": 16,
"file_cache_size_in_mb": 500,
"row_cache_size_in_mb": 100
}
Expand All @@ -269,22 +297,67 @@ func TestCreateJsonConfig(t *testing.T) {
},
want: `{
"cassandra-yaml": {
"num_tokens": 256,
"start_rpc": false,
"thrift_prepared_statements_cache_size_mb": 1
}
}`,
},
{
name: "[4.0] start_rpc, thrift_prepared_statements_cache_size_mb",
cassandraVersion: "4.0",
name: "[4.0.0] start_rpc, thrift_prepared_statements_cache_size_mb",
cassandraVersion: "4.0.0",
config: &api.CassandraConfig{
CassandraYaml: &api.CassandraYaml{
StartRpc: boolPtr(false),
ThriftPreparedStatementCacheSizeMb: intPtr(1),
},
},
want: `{
"cassandra-yaml": {
"cassandra-yaml": {
"num_tokens": 16
}
}`,
},
{
name: "[3.11.11] num_tokens",
cassandraVersion: "3.11.11",
config: &api.CassandraConfig{
CassandraYaml: &api.CassandraYaml{
NumTokens: intPtr(32),
},
},
want: `{
"cassandra-yaml": {
"num_tokens": 32
}
}`,
},
{
name: "[4.0.0] num_tokens",
cassandraVersion: "4.0.0",
config: &api.CassandraConfig{
CassandraYaml: &api.CassandraYaml{
NumTokens: intPtr(32),
},
},
want: `{
"cassandra-yaml": {
"num_tokens": 32
}
}`,
},
{
name: "[4.0.0] allocate_tokens_for_local_replication_factor",
cassandraVersion: "4.0.0",
config: &api.CassandraConfig{
CassandraYaml: &api.CassandraYaml{
AllocateTokensForLocalReplicationFactor: intPtr(5),
},
},
want: `{
"cassandra-yaml": {
"allocate_tokens_for_local_replication_factor": 5,
"num_tokens": 16
}
}`,
},
Expand All @@ -307,29 +380,18 @@ func TestCreateJsonConfig(t *testing.T) {
}

for _, tc := range tests {
var err error
tc.got, err = CreateJsonConfig(tc.config, tc.cassandraVersion)
if err != nil {
t.Errorf("%s - failed to create json dcConfig: %s", tc.name, err)
continue
}

expected, err := gabs.ParseJSON([]byte(tc.want))
if err != nil {
t.Errorf("%s - failed to parse expected value: %s", tc.name, err)
continue
}

actual, err := gabs.ParseJSON(tc.got)
if err != nil {
t.Errorf("%s - failed to parse actual value: %s", tc.name, err)
continue
}

if !reflect.DeepEqual(expected, actual) {
t.Errorf("%s - wanted: %s, got: %s", tc.name, expected, actual)
}
t.Run(tc.name, func(t *testing.T) {
var err error
tc.got, err = CreateJsonConfig(tc.config, tc.cassandraVersion)
require.NoError(t, err, "failed to create json dcConfig")
expected, err := gabs.ParseJSON([]byte(tc.want))
require.NoError(t, err, "failed to parse expected value")
actual, err := gabs.ParseJSON(tc.got)
require.NoError(t, err, "failed to parse actual value")
assert.Equal(t, expected, actual)
})
}

}

func intPtr(n int) *int {
Expand Down
Loading

0 comments on commit 608eb39

Please sign in to comment.