spark批量写入redis

最近工作中,在融合数据的时候,需要将10亿+的记录push到redis中,运维的同学帮忙搭建好redis集群,100主 + 100 从 (单节点8G),最开始打算第一次批量写入使用spark去写入到redis,因为数据存放在Hive表。
一、相关依赖的jar包

compile group: 'com.redislabs', name: 'spark-redis', version: '2.3.0'
compile group: 'redis.clients', name: 'jedis', version: '2.9.0'
compile group: 'org.apache.commons', name: 'commons-pool2', version: '2.0'

我用gradle管理依赖,如果用maven也可以去maven官网寻找。

二、测试用例
1、方法

sc.toRedisKV() 存储key、value字符串
具体实现:
def toRedisKV(kvs: RDD[(String, String)], ttl: Int = 0)
               (implicit redisConfig: RedisConfig = new RedisConfig(new RedisEndpoint(sc.getConf))) {
    kvs.foreachPartition(partition => setKVs(partition, ttl, redisConfig))
  }
 /**
    * @param arr k/vs which should be saved in the target host
    *            save all the k/vs to the target host
    * @param ttl time to live
    */
  def setKVs(arr: Iterator[(String, String)], ttl: Int, redisConfig: RedisConfig) {
    arr.map(kv => (redisConfig.getHost(kv._1), kv)).toArray.groupBy(_._1).
      mapValues(a => a.map(p => p._2)).foreach {
      x => {
        val conn = x._1.endpoint.connect()
        val pipeline = conn.pipelined
        if (ttl <= 0) {
          x._2.foreach(x => pipeline.set(x._1, x._2))
        }
        else {
          x._2.foreach(x => pipeline.setex(x._1, ttl, x._2))
        }
        pipeline.sync
        conn.close
      }
    }
  }


sc.toRedisHASH() 存储hash map
/**
    * @param kvs      Pair RDD of K/V
    * @param hashName target hash's name which hold all the kvs
    * @param ttl time to live
    */
  def toRedisHASH(kvs: RDD[(String, String)], hashName: String, ttl: Int = 0)
                 (implicit redisConfig: RedisConfig = new RedisConfig(new RedisEndpoint(sc.getConf))) {
    kvs.foreachPartition(partition => setHash(hashName, partition, ttl, redisConfig))
  }
 /**
    * @param hashName
    * @param arr k/vs which should be saved in the target host
    *            save all the k/vs to hashName(list type) to the target host
    * @param ttl time to live
    */
  def setHash(hashName: String, arr: Iterator[(String, String)], ttl: Int, redisConfig: RedisConfig) {
    val conn = redisConfig.connectionForKey(hashName)
    val pipeline = conn.pipelined
    arr.foreach(x => pipeline.hset(hashName, x._1, x._2))
    if (ttl > 0) pipeline.expire(hashName, ttl)
    pipeline.sync
    conn.close
  }
// 后续再补充
sc.toRedisFixedLIST()
sc.toRedisLIST()
sc.toRedisSET()
sc.toRedisZSET()

2、测试

val activeRiskTableName = "hm_service_risk.test_active_risk_base_db"
    val today = DateUtil.format(DateUtil.getDayBegin, "yyyyMMdd")
    val dataFrame = spark.read.table(activeRiskTableName).filter($"stat_date".equalTo(today)).
      select("id", "update_time", "risk").
      withColumn("update_time", to_timestamp($"update_time", "yyyy-MM-dd HH:mm:ss"))

    val redisHost = "localhost"
    val redisPort: Int = 6379
    val redisAuth: String = ""
    val redisDataRdd = dataFrame.map(row => {
      val id = row.getAs[String]("id")
      val updateTime = row.getAs[Int]("update_time")
      val risk = row.getAs[Int]("risk")
      val redisKey = prefix + AESUtils.aesEncrypt(id)
      val json = new JSONObject()
      json.put("update_time", updateTime)
      json.put("risk", risk)
      (redisKey, json.toJSONString)
    }).rdd

    val redisConfig = new RedisConfig(RedisEndpoint(redisHost, redisPort, redisAuth))
    sc.toRedisKV(redisDataRdd)(redisConfig)

临时工作没深入研究,后续有时间深入研究,再补充

### 回答1: b'sparkstreaming写入redis'的意思是询问如何将Spark Streaming产生的数据写入Redis中。答案可以是使用Redis对应的Java API或Redis的Python客户端库等工具,将数据按照指定的格式格式化并写入Redis中。 ### 回答2: Spark Streaming可以通过Redis作为数据存储和处理的一种选择。在Spark Streaming中,可以使用Redis作为数据源和数据目的地,将实时流数据写入Redis中。 在使用Spark Streaming写入Redis时,首先需要通过创建一个Redis连接池或者直接连接Redis服务器来建立与Redis的连接。可以使用`Jedis`或`Lettuce`等Java库来实现与Redis的连接。 在Spark Streaming的DStream中,可以通过`foreachRDD`函数来对每个批次的RDD进行操作。在这个函数中,可以使用`foreachPartition`函数将分区中的数据写入Redis中。 具体地,可以在`foreachPartition`函数中创建一个Redis连接,并在每个分区中迭代处理数据,并将数据写入Redis中。 示例代码如下: ```scala import redis.clients.jedis.Jedis val stream = ... // 从实时数据源获取DStream stream.foreachRDD { rdd => rdd.foreachPartition { partition => val jedis = new Jedis("localhost") // 连接Redis服务器 partition.foreach { data => // 将数据写入Redis中 jedis.set(data._1, data._2) } jedis.close() // 关闭Redis连接 } } // 启动Streaming应用 ssc.start() ssc.awaitTermination() ``` 上述代码中的`data._1`和`data._2`代表了从实时流中获得的每一条数据的键和值。可以根据实际需求进行相应的处理和转换。 需要注意的是,在使用Spark Streaming写入Redis时,需要考虑到数据的一致性和可靠性。可以使用Redis的事务机制和持久化功能来确保数据写入的完整性和持久性。 综上所述,使用Spark Streaming写入Redis可以通过连接Redis服务器,并在分区中迭代处理数据并写入Redis中来实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值