通过GoCQL在ScyllaDB上进行阻塞/一致/可预测的回复/请求。

huangapple go评论122阅读模式
英文:

Make a blocking/consistent/predictable reply/request on ScyllaDB via GoCQL

问题

有时候运行命令时会显示超时错误(gocql: no response received from cassandra within timeout period),例如:

  1. package main
  2. import "fmt"
  3. import "github.com/gocql/gocql"
  4. import "time"
  5. import "log"
  6. func main() {
  7. clust := gocql.NewCluster(`172.17.0.2`) // docker@localhost
  8. clust.Keyspace = `test4`
  9. clust.RetryPolicy = &gocql.SimpleRetryPolicy{NumRetries: 3}
  10. db, err := clust.CreateSession()
  11. defer db.Close()
  12. if err != nil {
  13. log.Fatal(err)
  14. return
  15. }
  16. fmt.Println(`test4: scylladb`)
  17. if err := db.Query(`DROP TABLE test4`).Exec(); err != nil {
  18. log.Println(err)
  19. }
  20. if err := db.Query(`CREATE TABLE test4 (bucket text, k text, v TEXT, PRIMARY KEY(bucket,k))`).Exec(); err != nil {
  21. log.Fatal(err)
  22. return
  23. }
  24. const max = 999
  25. const jump = 40
  26. t := time.Now()
  27. for x := 1; x <= max; x++ {
  28. err = db.Query(fmt.Sprintf(`INSERT INTO test4(bucket,k,v)VALUES('foo','%05d','%05d')`, x, x)).Exec()
  29. if err != nil {
  30. log.Fatal(err)
  31. return
  32. }
  33. if x % 200 == 0 {
  34. fmt.Print(`.`)
  35. }
  36. }
  37. dur := time.Now().Sub(t)
  38. fmt.Printf("INSERT: %v (%.2f ms/op)\n", dur, float64(dur.Nanoseconds()) / 1000000 / max)
  39. t = time.Now()
  40. for x := 1; x <= max; x++ {
  41. err = db.Query(fmt.Sprintf(`UPDATE test4 SET v = '%06d' WHERE bucket = 'foo' AND k = '%05d'`, x, x)).Exec()
  42. if err != nil {
  43. log.Fatal(err)
  44. return
  45. }
  46. if x % 200 == 0 {
  47. fmt.Print(`.`)
  48. }
  49. }
  50. dur = time.Now().Sub(t)
  51. fmt.Printf("UPDATE: %v (%.2f ms/op)\n", dur, float64(dur.Nanoseconds()) / 1000000 / max)
  52. t = time.Now()
  53. ops := int64(0)
  54. for y := 2; y < jump; y++ {
  55. for x := max - 1; x > 0; x -= y {
  56. ops++
  57. iter := db.Query(fmt.Sprintf(`SELECT k, v FROM test4 WHERE bucket = 'foo' AND k >= '%05d' ORDER BY k ASC LIMIT %d`, x, y * y)).Iter()
  58. for {
  59. m := map[string]interface{}{}
  60. if !iter.MapScan(m) {
  61. break
  62. }
  63. }
  64. iter.Close()
  65. if ops % 500 == 0 {
  66. fmt.Print(`.`)
  67. }
  68. }
  69. for x := 1; x < max; x += y {
  70. ops++
  71. iter := db.Query(fmt.Sprintf(`SELECT k, v FROM test4 WHERE bucket = 'foo' AND k <= '%05d' ORDER BY k DESC LIMIT %d`, x, y * y)).Iter()
  72. for {
  73. m := map[string]interface{}{}
  74. if !iter.MapScan(m) {
  75. break
  76. }
  77. }
  78. iter.Close()
  79. if ops % 500 == 0 {
  80. fmt.Print(`.`)
  81. }
  82. }
  83. }
  84. dur = time.Now().Sub(t)
  85. fmt.Printf("SELECT: %v (%.2f ms/op)\n", dur, float64(dur.Nanoseconds()) / 1000000 / float64(ops))
  86. }

它显示不一致的输出:

  1. $ go run scylla.go
  2. test4: scylladb
  3. 2017/05/16 12:09:05 gocql: no response received from cassandra within timeout period
  4. 2017/05/16 12:09:05 gocql: no response received from cassandra within timeout period
  5. exit status 1
  6. $ go run scylla.go
  7. test4: scylladb
  8. ....INSERT: 188.277521ms (0.19 ms/op)
  9. ....UPDATE: 150.403282ms (0.15 ms/op)
  10. .............SELECT: 5.357779756s (0.82 ms/op)
  11. $ go run scylla.go
  12. test4: scylladb
  13. 2017/05/16 12:09:50 gocql: no response received from cassandra within timeout period
  14. ....INSERT: 142.91132ms (0.14 ms/op)
  15. ....UPDATE: 144.272872ms (0.14 ms/op)
  16. .............SELECT: 5.268130283s (0.81 ms/op)
  17. $ go run scylla.go
  18. test4: scylladb
  19. 2017/05/16 12:10:00 gocql: no response received from cassandra within timeout period
  20. 2017/05/16 12:10:00 gocql: no response received from cassandra within timeout period
  21. exit status 1
  22. $ go run scylla.go
  23. test4: scylladb
  24. ....INSERT: 184.402052ms (0.18 ms/op)
  25. ....UPDATE: 158.200184ms (0.16 ms/op)
  26. .............SELECT: 5.345212835s (0.82 ms/op)

如何使其保持一致?我需要确保命令是否成功完成。或者我应该手动循环执行 DROP TABLE/CREATE TABLE 命令吗?

英文:

Sometimes when running a command it shows a timeout (gocql: no response received from cassandra within timeout period), for example:

  1. package main
  2. import &quot;fmt&quot;
  3. import &quot;github.com/gocql/gocql&quot;
  4. import &quot;time&quot;
  5. import &quot;log&quot;
  6. func main() {
  7. clust := gocql.NewCluster(`172.17.0.2`) // docker@localhost
  8. clust.Keyspace = `test4`
  9. clust.RetryPolicy = &amp;gocql.SimpleRetryPolicy{NumRetries: 3}
  10. db, err := clust.CreateSession()
  11. defer db.Close()
  12. if err != nil {
  13. log.Fatal(err)
  14. return
  15. }
  16. fmt.Println(`test4: scylladb`)
  17. if err := db.Query(`DROP TABLE test4`).Exec(); err != nil {
  18. log.Println(err)
  19. }
  20. if err := db.Query(`CREATE TABLE test4 (bucket text, k text, v TEXT, PRIMARY KEY(bucket,k))`).Exec(); err != nil {
  21. log.Fatal(err)
  22. return
  23. }
  24. const max = 999
  25. const jump = 40
  26. t := time.Now()
  27. for x := 1; x &lt;= max; x++ {
  28. err = db.Query(fmt.Sprintf(`INSERT INTO test4(bucket,k,v)VALUES(&#39;foo&#39;,&#39;%05d&#39;,&#39;%05d&#39;)`, x, x)).Exec()
  29. if err != nil {
  30. log.Fatal(err)
  31. return
  32. }
  33. if x % 200 == 0 {
  34. fmt.Print(`.`)
  35. }
  36. }
  37. dur := time.Now().Sub(t)
  38. fmt.Printf(&quot;INSERT: %v (%.2f ms/op)\n&quot;, dur, float64(dur.Nanoseconds()) / 1000000 / max)
  39. t = time.Now()
  40. for x := 1; x &lt;= max; x++ {
  41. err = db.Query(fmt.Sprintf(`UPDATE test4 SET v = &#39;%06d&#39; WHERE bucket = &#39;foo&#39; AND k = &#39;%05d&#39;`, x, x)).Exec()
  42. if err != nil {
  43. log.Fatal(err)
  44. return
  45. }
  46. if x % 200 == 0 {
  47. fmt.Print(`.`)
  48. }
  49. }
  50. dur = time.Now().Sub(t)
  51. fmt.Printf(&quot;UPDATE: %v (%.2f ms/op)\n&quot;, dur, float64(dur.Nanoseconds()) / 1000000 / max)
  52. t = time.Now()
  53. ops := int64(0)
  54. for y := 2; y &lt; jump; y++ {
  55. for x := max - 1; x &gt; 0; x -= y {
  56. ops++
  57. iter := db.Query(fmt.Sprintf(`SELECT k, v FROM test4 WHERE bucket = &#39;foo&#39; AND k &gt;= &#39;%05d&#39; ORDER BY k ASC LIMIT %d`, x, y * y)).Iter()
  58. for {
  59. m := map[string]interface{}{}
  60. if !iter.MapScan(m) {
  61. break
  62. }
  63. }
  64. iter.Close()
  65. if ops % 500 == 0 {
  66. fmt.Print(`.`)
  67. }
  68. }
  69. for x := 1; x &lt; max; x += y {
  70. ops++
  71. iter := db.Query(fmt.Sprintf(`SELECT k, v FROM test4 WHERE bucket = &#39;foo&#39; AND k &lt;= &#39;%05d&#39; ORDER BY k DESC LIMIT %d`, x, y * y)).Iter()
  72. for {
  73. m := map[string]interface{}{}
  74. if !iter.MapScan(m) {
  75. break
  76. }
  77. }
  78. iter.Close()
  79. if ops % 500 == 0 {
  80. fmt.Print(`.`)
  81. }
  82. }
  83. }
  84. dur = time.Now().Sub(t)
  85. fmt.Printf(&quot;SELECT: %v (%.2f ms/op)\n&quot;, dur, float64(dur.Nanoseconds()) / 1000000 / float64(ops))
  86. }

It shows inconsistent output:

  1. $ go run scylla.go
  2. test4: scylladb
  3. 2017/05/16 12:09:05 gocql: no response received from cassandra within timeout period
  4. 2017/05/16 12:09:05 gocql: no response received from cassandra within timeout period
  5. exit status 1
  6. $ go run scylla.go
  7. test4: scylladb
  8. ....INSERT: 188.277521ms (0.19 ms/op)
  9. ....UPDATE: 150.403282ms (0.15 ms/op)
  10. .............SELECT: 5.357779756s (0.82 ms/op)
  11. $ go run scylla.go
  12. test4: scylladb
  13. 2017/05/16 12:09:50 gocql: no response received from cassandra within timeout period
  14. ....INSERT: 142.91132ms (0.14 ms/op)
  15. ....UPDATE: 144.272872ms (0.14 ms/op)
  16. .............SELECT: 5.268130283s (0.81 ms/op)
  17. $ go run scylla.go
  18. test4: scylladb
  19. 2017/05/16 12:10:00 gocql: no response received from cassandra within timeout period
  20. 2017/05/16 12:10:00 gocql: no response received from cassandra within timeout period
  21. exit status 1
  22. $ go run scylla.go
  23. test4: scylladb
  24. ....INSERT: 184.402052ms (0.18 ms/op)
  25. ....UPDATE: 158.200184ms (0.16 ms/op)
  26. .............SELECT: 5.345212835s (0.82 ms/op)

How to make it consistent? I need to be sure if a command completed successfully.. Or should I loop the DROP TABLE/CREATE TABLE command manually?

答案1

得分: 2

DROP TABLECREATE TABLE比普通查询要花费更长的时间。你可以尝试增加这些查询的超时时间。

例如:clust.Timeout = 8 * time.Second

英文:

DROP TABLE and CREATE TABLE can take a lot longer than ordinary queries. You can try to increase the timeouts for these queries.

For example: clust.Timeout = 8 * time.Second

huangapple
  • 本文由 发表于 2017年5月16日 13:13:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/43992997.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定