當試圖幾千條記錄一次插入到遠程卡桑德拉分貝,我重複地遇到超時(5〜6千的元素連接速度慢)與NoHostAvailableException處理幻象DSL
錯誤:
All host(s) tried for query failed (tried: /...:9042
(com.datastax.driver.core.exceptions.OperationTimedOutException: [/...]
Timed out waiting for server response))
com.datastax.driver.core.exceptions.NoHostAvailableException:
All host(s) tried for query failed (tried: /...:9042
(com.datastax.driver.core.exceptions.OperationTimedOutException: [/...]
Timed out waiting for server response))
模型:
class RecordModel extends CassandraTable[ConcreteRecordModel, Record] {
object id extends StringColumn(this) with PartitionKey[String]
...
abstract class ConcreteRecordModel extends RecordModel
with RootConnector with ResultSetFutureHelper {
def store(rec: Record): Future[ResultSet] =
insert.value(_.id, rec.id).value(...).future()
def store(recs: List[Record]): Future[List[ResultSet]] = Future.traverse(recs)(store)
連接器:
val connector = ContactPoints(hosts).withClusterBuilder(
_.withCredentials(
config.getString("username"),
config.getString("password")
).withPoolingOptions(
new PoolingOptions().setCoreConnectionsPerHost(HostDistance.LOCAL, 4)
.setMaxConnectionsPerHost(HostDistance.LOCAL, 10)
.setCoreConnectionsPerHost(HostDistance.REMOTE, 2)
.setMaxConnectionsPerHost(HostDistance.REMOTE, 4)
.setMaxRequestsPerConnection(HostDistance.LOCAL, 32768)
.setMaxRequestsPerConnection(HostDistance.REMOTE, 2000)
.setPoolTimeoutMillis(10000)
)
).keySpace(keyspace)
我已經嘗試調整池選項,分開和一起。但是,即使加倍所有的REMOTE
設置並沒有改變超時明顯
目前的解決方法,這是我想避免 - 分裂清單分成批次,等待每完成:
def store(recs: List[Record]): Future[List[ResultSet]] = {
val rs: Iterator[List[ResultSet]] = recs.grouped(1000) map { slice =>
Await.result(Future.traverse(slice)(store), 100 seconds)
}
Future.successful(rs.to[List].flatten)
}
會是什麼處理這個問題的好方法?
謝謝
編輯
的錯誤確實表明未能/超載集羣,但我懷疑這裏的網絡發揮了重要作用。上面提供的數字來自遠程機器。當同一個數據中心的機器提供相同的C *時,它們要高得多。另一個可疑的細節是,用quill餵養相同的C *實例不會遇到任何超時問題,遠程或不遠。
我真的不喜歡節流的是批量大小是隨機的和靜態的,而它們應該是適應性的。
IIUC你建議的方式去增加更多的機器?這可以完成,但我仍然想知道接受請求的數量很少。在上面添加了一些細節,也許你有一個想法。你可以分享一些合理的重試策略的細節嗎?什麼是集羣恢復的合理時間。已經嘗試過增加超時退出,但有時甚至在30秒後重試似乎要早。 – kostja
使用羽毛筆時,您是否執行相同的查詢?這些例外情況肯定發生在超時客戶端,但是由於集羣花費太長時間來響應結果。你在服務器的日誌中看到很多GC嗎?如果羣集沒有出現CPU/IO明顯負載的情況,那麼您也可以增加客戶端的讀取超時 http://docs.datastax.com/en/drivers/java/2.1/com/datastax/驅動器/核心/ SocketOptions.html#setReadTimeoutMillis,內部 - – Kurt