Spark批量讀取Redis資料-Pipeline(Scala)

來源:互聯網
上載者:User

最近在處理資料時,需要將未經處理資料與Redis的資料進行join,在讀取Redis的過程中,碰到了一些問題,順便做個筆記,希望對其他同學也有所協助。實驗過程中,當資料量還是十萬層級的時候,逐個讀取Redis並無壓力;但當資料量達到千萬層級時,問題就油然而生了,即使是使用Spark的mapPartitions也無法解決。因此,就考慮使用Redis的pipeline了(如果你有更好的方法,還請不吝賜教)。PS:本文主要針對的是Scala語言,因為目前在網上還沒有看到Scala版本的Redis pipeline,希望此文能給初學者提供一個參考。

文章會先介紹如何使用Scala逐個去讀取Redis資料,然後再介紹pipeline的使用。 方法一、逐行讀取Redis資料

在本文,主要使用的是redis.clients.jedis.Jedis庫,如果你是使用sbt來運行spark,可以在build.sbt中做如下配置:

name := "sparkRedisExp"version := "1.0.0"scalaVersion := "2.10.4"libraryDependencies += "org.apache.spark" %% "spark-core" % "1.3.1"libraryDependencies += "redis.clients" % "jedis" % "2.6.2"resolvers += "Akka Respository" at "http://repo.akka.io/releases/"

相應的jedis庫可以到Github中下載 jedis-2.6.2.jar:https://github.com/csuldw/WorkUtils/tree/master/Spark/deps。下面請看詳細內容。 匯入Redis庫

首先匯入redis庫,這裡使用redis.clients.jedis.Jedis庫。

import redis.clients.jedis.Jedis
串連Redis

然後串連Redis,主要設定redisHost、redisPort,如果有密碼,需要進行密碼驗證。

val redisHost = "localhost"val redisPort = 8080val redisClient = new Jedis(redisHost, redisPort)redisClient.auth(redisPassword)
讀取Redis資料

接下來,就可以直接使用get擷取redis資料

val keys = Array("key1", "key2", "key3", "key4")for(key <- keys){  println(redisClient.get(key))}

上述方法並沒有使用Redis的pipeline,當資料較少的時候,可以用來使用。下面介紹如何使用pipeline來批量讀取Redis資料。 方法二、使用Redis pipeline批量讀取Redis資料

相對於第一種方法,這裡需要額外引入兩個庫,redis.clients.jedis.Pipeline和redis.clients.jedis.Response。 匯入相關庫

import redis.clients.jedis.Jedisimport redis.clients.jedis.Pipelineimport redis.clients.jedis.Response
串連Redis

此操作與上面的一樣,如下:

val redisHost = "localhost"val redisPort = 8080val redisClient = new Jedis(redisHost, redisPort)redisClient.auth(redisPassword)
使用pipeline讀取資料之一(簡化版)

先給出代碼,下面再做解釋。

var tempRedisRes = Map[String, Response[String]]()val keys = Array("key1", "key2", "key3", "key4")val pp = redisClient.pipelined()for(key <- keys){  tempRedisRes ++= Map(key -> pp.get(key)) }pp.sync()

因為redis.clients.jedis.Jedis的pipelined下的get方法擷取的是一個Response[String]類型的傳回值,所以上面定義了一個臨時變數Map[String, Response[String]]類型的tempRedisRes,key是String類型,value是Response[String]類型,用於儲存pp.get(key)的傳回值。當for迴圈執行完之後,使用sync同步即可。這樣便實現了Redis的Pipeline功能。 使用pipeline讀取資料之二(強化版)

為了防止串連Redis時的意外失敗,我們需要設定一個嘗試次數,確保資料一定程度上的正確性。因此,在上面的代碼外面增加一層串連邏輯,如下:

var tempRedisRes = Map[String, Response[String]]()val keys = Array("key1", "key2", "key3", "key4")var tryTimes = 2var flag = falsewhile(tryTimes > 0 && !flag) {  try{    val pp = redisClient.pipelined()    for(key <- keys){      tempRedisRes ++= Map(key -> pp.get(key))    }    pp.sync()    flag = true  }catch {    case e: Exception => {      flag = false      println("Redis-Timeout" + e)      tryTimes = tryTimes - 1    }  }finally{    redisClient.disconnect()  }}

再次說明:pp.get()得到的是一個Response[String]的結果,詳細內容請查看redis-clients-jedis-Pipeline.

Ok,本文內容到此結束,更多精彩文章,請進 http://www.csuldw.com.

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.