Use Alpakka Cassandra 2.0.2 instead of DataStax Java Driver 3.11.0#54
Use Alpakka Cassandra 2.0.2 instead of DataStax Java Driver 3.11.0#54
Conversation
a381893 to
667d516
Compare
| # If we prefer to override such settings for each tenant, | ||
| # we must use a different path for each tenant by overriding this setting. | ||
| # See also https://docs.datastax.com/en/developer/java-driver/latest/manual/core/configuration/ | ||
| datastax-java-driver-config = "datastax-java-driver" |
There was a problem hiding this comment.
次の driver に関連する項目は datastax-java-driver から設定できます。
- contact-points
- authentication
- socket
- retry-policy
- load-balancing-policy
| # We can set different profiles for reads and writes. | ||
| # See also https://docs.datastax.com/en/developer/java-driver/latest/manual/core/configuration/#execution-profiles | ||
| read-profile = "lerna-util-sequence-profile" | ||
| write-profile = "lerna-util-sequence-profile" |
There was a problem hiding this comment.
profile 機能を活用し、consistency level 等が設定できます。
profile の概要は次の URL から確認できます。
https://docs.datastax.com/en/developer/java-driver/4.13/manual/core/configuration/#execution-profiles
デフォルト構成では、read, write の profile は同じものを使います。
必要に応じてprofile 名を変更することで、read と write に異なる profile を使用することもできます。
lerna-util-sequence/src/main/scala/lerna/util/sequence/SequenceFactoryConfig.scala
Show resolved
Hide resolved
lerna-util-sequence/src/main/scala/lerna/util/sequence/SequenceFactoryConfig.scala
Show resolved
Hide resolved
| @@ -284,7 +288,7 @@ private[sequence] final class SequenceStore( | |||
| maybeRow <- executeRead( | |||
| selectSequenceReservationStatement.bind(sequenceId, normalizeSubId(sequenceSubId), Integer.valueOf(nodeId)), | |||
There was a problem hiding this comment.
Statement は immutable な builder API になりました。
https://docs.datastax.com/en/developer/java-driver/4.13/upgrade_guide/#statements
もしも Statement を mutable API を使って構築している場合には書き換えが必要です。
$ git grep -iF 'Statement' -- lerna-util-sequence
lerna-util-sequence/src/main/scala/lerna/util/sequence/CassandraStatements.scala:private[sequence] final class CassandraStatements(config: SequenceFactoryCassandraConfig) {
lerna-util-sequence/src/main/scala/lerna/util/sequence/SequenceStore.scala:import com.datastax.oss.driver.api.core.cql.{ PreparedStatement, Row, Statement }
lerna-util-sequence/src/main/scala/lerna/util/sequence/SequenceStore.scala: selectSequenceReservationStatement: PreparedStatement,
lerna-util-sequence/src/main/scala/lerna/util/sequence/SequenceStore.scala: insertSequenceReservationStatement: PreparedStatement,
lerna-util-sequence/src/main/scala/lerna/util/sequence/SequenceStore.scala: val statements = new CassandraStatements(config)
lerna-util-sequence/src/main/scala/lerna/util/sequence/SequenceStore.scala: private[this] def executeWrite[T <: Statement[T]](
lerna-util-sequence/src/main/scala/lerna/util/sequence/SequenceStore.scala: statement: Statement[T],
lerna-util-sequence/src/main/scala/lerna/util/sequence/SequenceStore.scala: session.executeAsync(statement.setExecutionProfileName(config.writeProfileName)).toScala.map(_ => Done)
lerna-util-sequence/src/main/scala/lerna/util/sequence/SequenceStore.scala: private[this] def executeRead[T <: Statement[T]](
lerna-util-sequence/src/main/scala/lerna/util/sequence/SequenceStore.scala: statement: Statement[T],
lerna-util-sequence/src/main/scala/lerna/util/sequence/SequenceStore.scala: session.executeAsync(statement.setExecutionProfileName(config.readProfileName)).toScala.map { asyncResult =>
lerna-util-sequence/src/main/scala/lerna/util/sequence/SequenceStore.scala: _ <- session.executeAsync(statements.createKeyspace).toScala
lerna-util-sequence/src/main/scala/lerna/util/sequence/SequenceStore.scala: _ <- session.executeAsync(statements.useKeyspace).toScala
lerna-util-sequence/src/main/scala/lerna/util/sequence/SequenceStore.scala: _ <- session.executeAsync(statements.createTable).toScala
lerna-util-sequence/src/main/scala/lerna/util/sequence/SequenceStore.scala: selectSequenceReservationStatement <- session.prepareAsync(statements.selectSequenceReservation).toScala
lerna-util-sequence/src/main/scala/lerna/util/sequence/SequenceStore.scala: insertSequenceReservationStatement <- session.prepareAsync(statements.insertSequenceReservation).toScala
lerna-util-sequence/src/main/scala/lerna/util/sequence/SequenceStore.scala: selectSequenceReservationStatement,
lerna-util-sequence/src/main/scala/lerna/util/sequence/SequenceStore.scala: insertSequenceReservationStatement,
lerna-util-sequence/src/main/scala/lerna/util/sequence/SequenceStore.scala: selectSequenceReservationStatement.bind(sequenceId, normalizeSubId(sequenceSubId), Integer.valueOf(nodeId)),
lerna-util-sequence/src/main/scala/lerna/util/sequence/SequenceStore.scala: insertSequenceReservationStatement.bind(
lerna-util-sequence/src/test/scala/lerna/util/sequence/SequenceTestkit.scala:import com.datastax.oss.driver.api.core.cql.SimpleStatement
lerna-util-sequence/src/test/scala/lerna/util/sequence/SequenceTestkit.scala: SimpleStatement
There was a problem hiding this comment.
確認する限り、書き換えが必要なコードはありませんでした。
| selectSequenceReservationStatement.setRetryPolicy(config.cassandraReadRetryPolicy), | ||
| insertSequenceReservationStatement.setRetryPolicy(config.cassandraWriteRetryPolicy), | ||
| selectSequenceReservationStatement, | ||
| insertSequenceReservationStatement, |
There was a problem hiding this comment.
RetryPolicy は profile ごとに指定するようになります。
executeWrite, executeRead メソッドで profile を指定しています。
ea57405 to
22bb101
Compare
| val selectSequenceReservation: SimpleStatement = | ||
| SimpleStatement | ||
| .newInstance(selectSequenceReservationCQL) | ||
| .setIdempotent(true) |
There was a problem hiding this comment.
Statement (a.k.a. Query) に 冪等 (Idempotent) かどうかを設定するようにします。
QueryBuilder を使わない限り、冪等かどうかは手動で設定する必要があります。
冪等でない Query は driver ではリトライされません。
Query が冪等かどうか設定されていない場合には、
setDefaultIdempotence(true)と明示しない限り (3.xの場合)、デフォルトは冪等ではないと扱われます。
4.x の場合は、設定項目 basic.request.default-idempotence があります。
https://docs.datastax.com/en/developer/java-driver/3.11/manual/retries/#retries
https://docs.datastax.com/en/developer/java-driver/3.11/manual/idempotence/#query-idempotence
https://docs.datastax.com/en/developer/java-driver/4.13/manual/core/retries/#retries
https://docs.datastax.com/en/developer/java-driver/4.13/manual/core/idempotence/
selectSequenceReservationStatement および insertSequenceReservationStatement が冪等な CQL を実行していれば、.setIdempotence(true) と設定することでRetry Policy を使った driver でのリトライが行われるようになります。5つの CQL は冪等であるため、.setIdempotence(true) を使用しました。
冪等の設定は、prepared statement 、 bounded statement を介した場合でも引き継がれます。
ドキュメントから確認することができます。
https://docs.datastax.com/en/developer/java-driver/4.13/manual/core/idempotence/#:~:text=When%20you%20prepare%20a%20statement,%20its%20idempotence%20carries%20over%20to%20bound%20statements:
また、4.x では冪等を明示しない場合のデフォルト値を、設定 basic.request.default-idempotence で指定することができます。デフォルト値は false です。この設定が true に設定された場合でも、冪等を明示していない、冪等でない Query が 誤って 冪等であると判断されないように、冪等でない Query の場合には .setIdempotence(false) を明示するほうが安全だと思われます。
aed0c97 to
0665c95
Compare
| import com.datastax.driver.core.policies._ | ||
| import akka.actor.ClassicActorSystemProvider | ||
| import com.datastax.oss.driver.api.core.config.DriverConfigLoader | ||
| import com.datastax.oss.driver.internal.core.config.typesafe.DefaultDriverConfigLoader |
There was a problem hiding this comment.
バイナリの後方互換性について、注意事項があります。
#54 (comment) のディスカッションを参照してください。
0665c95 to
af561da
Compare
| Dependencies.Akka.actorTyped, | ||
| Dependencies.Akka.actorTestKitTyped % Test, | ||
| Dependencies.Akka.actorTestKitTyped % Test, | ||
| Dependencies.ScalaLang.scalaJava8Compat % Test, |
There was a problem hiding this comment.
scala/scala-java8-compat: A Java 8 compatibility kit for Scala.
幾つか追加したテストで Java Optional => Scala Option に変換する等のために必要です。
3bacc8a to
1dd93d7
Compare
Here is the upgrade guide. https://docs.datastax.com/en/developer/java-driver/4.13/upgrade_guide Note that the Maven Coordinates is changed.
1dd93d7 to
df339c4
Compare
a9eac9f to
bfe5bb7
Compare
It would make us easy to maintain binary backward compatibility.
Feedback from code review. We prefer to handle possible exceptions explicitly.
03d7383 to
785eee8
Compare
It could provide * Customize Session Provider * Cassandra's contact points discovery via Akka Discovery
| # we must use a different path for each tenant by overriding this setting. | ||
| # See also https://docs.datastax.com/en/developer/java-driver/4.6/manual/core/configuration/ | ||
| datastax-java-driver-config = "datastax-java-driver" | ||
|
|
There was a problem hiding this comment.
@xirc 設定項目 session-provider、service-discovery、datastax-java-driver-config が alpakka.cassandra と同じ構成になっているようなので、設定項目を次のように継承するのはどうでしょうか?
default = ${alpakka.cassandra} {
# Profiles to use.
# We can set different profiles for reads and writes.
# See also https://docs.datastax.com/en/developer/java-driver/4.6/manual/core/configuration/#execution-profiles
read-profile = "lerna-util-sequence-profile"
... 略 ...キーの衝突を避けるため、次のように設定を継承するための新しい設定項目を作っても良いかもしれません。
defualt {
alpakka.cassandra = ${alpakka.cassandra}
# Profiles to use.
# We can set different profiles for reads and writes.
# See also https://docs.datastax.com/en/developer/java-driver/4.6/manual/core/configuration/#execution-profiles
read-profile = "lerna-util-sequence-profile"
... 略 ...
}config の継承については次のページに説明があります。
data-center-generic = { cluster-size = 6 } data-center-east = ${data-center-generic} { name = "east" } data-center-west = ${data-center-generic} { name = "west", cluster-size = 8 }lightbend/config: configuration library for JVM languages using HOCON files
このようにしておくと、ユーザーが session-provider や service-discovery を設定する場合 alpakka.cassandra 配下の設定を override しさえすれば、akka-persistence と lenra-util-sequence の両方に設定を反映できるようになるはずです。
また、Alpakka Cassandra が読み込む設定が増えたとしても lerna-util-sequence の reference.conf を改修する必要がなくなるはずです。
There was a problem hiding this comment.
継承することも可能だと思います。
継承する方法はデメリットもあるように思うので、慎重に検討する方が良いと思いました。
session-dispatcher
lerna.util.sequence.cassandra.default には alpakka.cassandra の設定がすべて含まれるわけではありません。
lerna.util.sequence.cassandra.default には設定項目 session-dispatcher がありません。
https://github.com/akka/alpakka/blob/v2.0.2/cassandra/src/main/resources/reference.conf#L13-L14
# The ExecutionContext to use for the session tasks and future composition. session-dispatcher = "akka.actor.default-dispatcher"
session-dispatcher は、CassandraSessionRegistry から使用されるようです。
https://github.com/akka/alpakka/blob/v2.0.2/cassandra/src/main/scala/akka/stream/alpakka/cassandra/scaladsl/CassandraSessionRegistry.scala#L92
val executionContext = system.dispatchers.lookup(sessionProviderConfig.getString("session-dispatcher"))
lerna-util-sequence は、CassandraSessionRegistry を使用していないため、session-dispatcher は使用されません。
使用されない設定項目が存在する場合に、ユーザが混乱することを懸念しています。
この設定項目は Cassandra Session に関連するタスクを実行する ExecutionContext を指定できるものだと理解していますが、
session-dispatcher が設定可能である場合、ユーザは SequenceStore 等が実行する CQL 実行の Future の合成に使用する ExecutionContext も指定できると想定する可能性がないかとも懸念しています。 設定項目のパスだけを見ると lerna.util.sequence.cassandra.default.session-dispatcher と見えるためです。
今後、仮に alpakka.cassandra の設定項目が増えた場合に、 lerna.util.sequence.cassandra.default にあるどの設定項目が使用されているのか判断することは難しくなっていくかもしれません。lerna.util.sequence.cassandra.default.alpakka.cassandra という設定項目を作ったとしても、同じような問題に遭遇するように思います。
akka-persistence-cassandra
akka-persistence-cassandra は、alpakka.cassandra の設定を継承していないように思います。
akka.persistence.cassandra { ... truncated
alpakka.cassandra.session-provider や alpakka.cassandra.service-discovery の設定を変更しても、akka-persistence-cassandra の振る舞いは変更されないのではないかと思います(実際に試したわけではありませんので確証はありません)。
必要であれば、ユーザは次のようにして設定項目を継承できます。
akka.persistence.cassandra.session-provider = ${alpakka.cassandra.session-provider}
lenra-util-sequence についても、同じようにユーザは継承を活用して同じ値を設定できます。
テスト
lerna.util.sequence.cassandra.defaultが alpakka.cassandra の設定項目を継承すると仮定します。alpakka.cassandra で設定項目が追加された際に、その設定項目が lerna-util-sequence においても意図通りに機能することをテストする必要があるように思います。Alpakka Cassandra のアップデートによって、テストしていない設定項目が追加されることに私たちはどのように対応するのか、検討しておく必要があります。
設定の後方互換性
「設定項目を継承する」ことにもメリットがあることも分かります。
設定項目を管理する手間を省くことができるかもしれません。
ただし、これはテストをしないということは意図していません。
設定項目についてテストを実施する必要があると思います。
CqlSessionProvider(system, config) が要求する設定項目が確実に存在することを保証できます。
CqlSessionProvider の要求する必須設定項目が増えた場合に、現在の実装では CqlSessionProvider の呼び出しで例外が発生することになると思われます。そのため、CqlSessionProvider を使用している CassandraSessionProvider.connect が 恐らく Failure を返すことになります。
回避策の1つとして、次のようにすることも考えられます。
val alpakkaCassandraConfig = system.classicSystem.settings.config.getConfig("alpakka.cassandra")
CqlSessionProvider(
system.classicSystem.asInstanceOf[ExtendedActorSystem],
validatedConfig.sessionProviderConfig.withFallback(alpakkaCassandraConfig),
)この方法にもデメリットがあるかもしれません。
例えば、ユーザが Alpakka Cassandra を全く別の用途に使っており、alpakka.cassandra.service-discovery.name を設定していたとします。ユーザが誤って lerna.util.sequence.cassandra.default.service-discovery.name を null にした場合、 alpakka.cassandra.service-discovery.name にフォールバックされるかもしれません(実際に試したわけではないため、確証はありません)。これは、lerna-util-sequence がユーザの意図しない Cassandra Cluster に接続する結果となる恐れがあります。Cassandra の認証情報を個別に管理していれば接続が拒否されるだけで済みますが、そうでない場合にどのようになるのか予想するのは難しいように思います。このようなフォールバックとなる振る舞いをユーザが意図的に設定したわけではないため、ユーザの混乱を招かないか懸念しています。
ユーザが予測しにくいデフォルトを設定するよりもエラーとなるようにしたいと思いました。
ただし、もっと上手な対処方法があればデメリットなしで設定を継承することも可能かもしれません。
There was a problem hiding this comment.
defualt { alpakka.cassandra = ${alpakka.cassandra}
提案頂いた設定項目の継承を調整して、次のように alpakka.cassandra へのパスを指定する方法も考えられそうです。
defualt {
alpakka-cassandra-config = "alpakka.cassandra"
read-profile = "lerna-util-sequence-profile"
// ... truncated
}
この方法であれば、設定の互換性は問題なくなるかもしれません。
また、lerna.util.sequence.cassandra.default.session-dispatcher のような使用しない設定項目がユーザに見えることもないように思うため、上手く解決できる可能性がありそうです。依然として alpakka.cassandra.session-dispatcher は使用しませんが、設定階層が異なるため混乱は招きにくくなりましたか?それともあまり改善できていませんか?
欠点は、Cassandraドライバの設定 (datastax-java-driver) にたどり着くために、いくつか設定項目を参照しながら辿る必要があることでしょうか。
There was a problem hiding this comment.
@xirc 様々な観点での検討ありがとうございます。
session-dispatcher
使用されない設定項目が存在する場合に、ユーザが混乱することを懸念しています。
ユーザーが混乱する可能性があることは私も同意です。
設定項目を継承する場合は、利用されない設定項目についてコメントで説明しておく必要があると思います。
akka-persistence-cassandra
akka-persistence-cassandra は、alpakka.cassandra の設定を継承していないように思います。
確かに継承していないですね。。
akka-cluster-sharding の coordinator-singleton と同じような構造になっているのかと思っていました。
コメント書く前に確認したほうが良かったですね。すみません。
coordinator-singleton = ${akka.cluster.singleton}
設定を共有する方法については、示してもらったユーザー自身による継承で対処してもらうという方針で良さそうです。
テスト
lerna.util.sequence.cassandra.defaultが alpakka.cassandra の設定項目を継承すると仮定します。alpakka.cassandra で設定項目が追加された際に、その設定項目が lerna-util-sequence においても意図通りに機能することをテストする必要があるように思います。
新しく追加された設定項目が lerna-util-sequence の振る舞いに影響を与えるものであれば、おっしゃるようにテストは必要だと思います。
設定の互換性
CqlSessionProvider の要求する必須設定項目が増えた場合に、現在の実装では CqlSessionProvider の呼び出しで例外が発生することになると思われます。
lerna-util-sequence が依存しているものよりも新しい Alpakka Cassandra を利用した akka-persistence-cassandra がリリースされ、ユーザーがその新しい akka-persistence-cassandra を使う可能性があることも検討に加えたほうが良いかもしれません。
akka-persistence-cassandra が依存する Alpakka Cassandra のバージョンで新しい設定項目が追加されている場合にランタイムエラーが発生する可能性があります。
このことについては次のような対処方法があるかなと思いました。
- Alpakka Cassandra の設定項目を継承して設定項目が追加されたとしても設定項目不足によるランタイムエラーが発生するのを回避する
- 設定項目に互換性のないバージョンを利用したときに発生するランタイムエラーはユーザー自身に解決してもらう
- ユーザーに lerna-util-sequence が依存する Alpakka Cassandra と同じバージョンの Alpakka Cassandra に依存した akka-persistence-cassandra を使ってもらう
そもそもは互換性の問題を回避するために Cassandra Driver ではなく、Alpakka Cassandra に依存することを選択したので、目的に反する 3 の選択肢は選ばないほうが良い気がしています。
1 はユーザーがランタイムエラーに遭遇する可能性を下げられますが、新しい設定項目のデフォルト値が lerna-util-sequence の振る舞いに悪影響を及ぼす可能性を完全には否定できません。
2 は新しい設定項目の読み込みが稀に行われるようなものだった場合、実運用に入ってからランタイムエラーに遭遇するかもしれないという点が気になります。不足している設定項目を起動直後にチェックして設定の追加をユーザーに促すなどすれば、この問題は軽減できそうです。
2 で事前チェックを行うのが安全性という点では良さそうですが、Alpakka Cassandra の新しい設定項目についてユーザーがどのような設定をすれば良いのか判断できるか不安があります。
この問題について何か追加のアイディアなどありますか?
There was a problem hiding this comment.
ページをリロードせず投稿してしまっていたので、直前のコメント見落としてました。
提案頂いた設定項目の継承を調整して、次のように alpakka.cassandra へのパスを指定する方法も考えられそうです。
lerna.util.sequence.cassandra.* で設定項目が見つからなかった場合にフォールバックする設定項目へのパスを指定するということですね。
alpakka.cassandra = ${alpakka.cassandra} と書いた場合と、withFallback で他の設定項目をマージ(と表現して良いのかわからないですが)した場合の Config の見え方には違いがありそうでしょうか?
直感的には同じような見え方をしそうな気がしています。
ConfigFactory.defaultReference() などで読み込んだときの見え方を意識されているということでしょうか?
There was a problem hiding this comment.
@negokaz
ありがとうございます。
コメントいただいた点についても検討が必要だと私も思いました。
Alpakka Cassandra の新しい設定項目についてユーザーがどのような設定をすれば良いのか判断できるか不安があります。
これについては、私にはアイディアはありません。
ドキュメントへのリンクを提供することはできるかもしれませんが、どの設定が使われるのかは、使用される Alpakka Cassandra のバージョンに大きく依存するように思いました。おそらくドキュメントを記載するにしても、「lerna-util-sequence が依存する Alpakka Cassandra と同じバージョンの Alpakka Cassandra に依存した Akka Persistence Cassandra を使ってください」と言及することになると予想しています。それ以外について動作保証をするのは難しいように思いました。
事前チェックについて
事前チェックを実施したい場合、例えば、Akka Management で使用できる Health checks • Akka Management を提供するのも良さそうだと思いました。その場合には、 lerna-util-sequence で HealthCheck 機能を提供するための実装が必要になるかもしれません。
設定のみを使って、事前チェックを厳密に行うのは難しいかもしれません。CqlSessionProvider (alpakka/CqlSessionProvider.scala at v2.0.2 · akka/alpakka) のソースコードを確認すると Akka Discovery を使う場合には CqlSessionProvider(...).connect() を呼び出すまで、設定が有効なものかどうかは確認することができないように読めました。恐らく、実際に CqlSession を確立するまでは、設定が有効かどうか判断することはできないかもしれません。これを踏まえて、Akka Management の ヘルスチェックを提供することを選択肢として挙げてみました。作業が多く必要そうなので実施するのは難しいかもしれません。
その他の方式案
例えば次のように、alpakka.cassandra の設定へのパスを指定するようにし、Apache Cassandra • Alpakka Documentation に記載のある CassandraSessionRegistry.get(system).sessionFor(sessionSettings) を使うようにします。これによって使われない設定というのはほぼ無くなるとは思いますし、設定の互換性を確保しやすいかもしれません。しかし、新しく alpakka.cassandra に追加された設定が、lerna-util-sequence に与える影響を推し量ることは依然として難しいとは思います。
実現するにはおそらくかなりの作業が必要そうなので選択肢としては難しいかもしれませんが、案としては考えられるため記録のためコメントに記載しておきます。Cassandra の Session のライフサイクルが変わるため、SequenceStore などの大幅な改修が必要そうだと予想しています。
defualt {
alpakka-cassandra-config = "alpakka.cassandra"
read-profile = "lerna-util-sequence-profile"
// ... truncated
}
最後の選択肢
次のコミットを revert することで、依存関係には Alpakka Cassandra を使いつつも、DataStax Java Driver を直接使用することに比較的近い Alpakka Cassandra の API のみを使うように戻すという選択肢があります。これによって、Akka Discovery による Cassandra の contact-points 検出などの機能は使用できなくなりますが、設定互換性などの問題は回避できると思います。「DataStax Java Driver のメジャーバージョンアップを実施する」という当初の目的も達成できています。
Use akka.stream.alpakka.cassandra.SessionProvider instead 9efa34f
There was a problem hiding this comment.
私も見落としてしまいました 🙇
alpakka.cassandra = ${alpakka.cassandra} と書いた場合と、withFallback で他の設定項目をマージ(と表現して良いのかわからないですが)した場合の Config の見え方には違いがありそうでしょうか?
直感的には同じような見え方をしそうな気がしています。
ConfigFactory.defaultReference() などで読み込んだときの見え方を意識されているということでしょうか?
おっしゃる通り、プログラムから見える設定に違いはほぼないと思います。
(もしかすると厳密には少し違うかもしれません)
ユーザが IntelliJ などの IDE で設定ファイルを開いた際の補完候補に違いが生まれるかもしれません。
プログラムで withFallback すれば、 想定していない設定項目をユーザに表示しなくても済むかもしれません。
There was a problem hiding this comment.
惜しいですが、「最後の選択肢」を使うのが現時点においては最良の選択のような気がしますね。
Alpakka Cassandra のほんの一部の機能しか使っていない経緯を後で追えるよう、CqlSessionProvider あたりのコメントにこのディスカッションへのリンクを残しておくのが良さそうな気がしました。
Use Alpakka Cassandra 2.0.2 instead of DataStax Java Driver 3.11.0.
DataStax Java Driver Upgrade
The Upgrade Guide: https://docs.datastax.com/en/developer/java-driver/4.6/upgrade_guide