簡體   English   中英

在Scala應用程序中緩存Cassandra表

[英]Cache Cassandra table in scala application

我需要從Cassandra中獲取一些數據,以用於Kafka-Streams流應用程序中的條目。 我需要對ID執行聯接。 我想設置一個緩存以節省查詢時間。 該表很簡單: id | name ---|----- 1 |Mike id | name ---|----- 1 |Mike

我的計划很簡單:從數據庫中查詢表,然后存儲到Map[Int, String]
主要問題是-表中的數據可能會更改,並且需要定期更新,因此我需要不時查詢它。

到目前為止,我已經提出了這樣的線程解決方案:

    // local database mirror
    class Mirror(user: String, password: String) extends Runnable {

      var database: Map[Int, String] =  Map[Int, String]() withDefaultValue "undefined"

      def run(): Unit = {
        update()
      }


      // 
      def update(): Unit = {
        println("update")
        database.synchronized {
          println("sync-update")        
          // val c = Driver.getConnection(...)
          // database = c.execute(select id, name from table). ...
          database += (1 -> "one")
          Thread.sleep(100)
          // c.close()
        }
      }

      def get(k: Int): Option[String] = {
        println("get")
        database.synchronized {
          println("sync-get")
          if (! (database contains k)) {
            update()
            database.get(k)
          } else {
            database.get(k)
          }
        }      
      }
    }

主要看起來像這樣:

    def main(args: Array[String]): Unit = {

      val db = new Mirror("u", "p")
      val ex = new ScheduledThreadPoolExecutor(1)
      val f = ex.scheduleAtFixedRate(db, 100, 100, TimeUnit.SECONDS)       

      while(true) { // simulate stream
        val res = db.get(1)
        println(res)
        Thread.sleep(10000)
      }       
    }

它似乎功能正常。 但是我的代碼有什么陷阱嗎? 尤其是我對updateget功能的線程安全性沒有信心。

如果您不反對使用Akka,我將介紹Akka Streams。 特別是Alpakka可以做到這一點。 如果沒有必要,則無需重新發明輪子。

話雖這么說,代碼具有以下問題:

  1. 如果Cassandra中的條目已更新,則對緩存的存在性檢查將無濟於事。 僅當您的緩存中缺少它們時才有用
  2. 如果您認為大多數時候緩存將具有當前條目,請考慮使用可重入讀寫鎖 如果您有多個線程調用鏡像,這將有助於爭用。

再次,我強烈建議您使用Alpakka查看Akka Streams,因為您可以使用該工具來完成所需的工作,而不必自己編寫一堆代碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM