Spark的将IP转换为Long型的方法

本文介绍了一种在Spark中将IP地址转换为Long型数据的方法。通过定义一个名为ip2Long的函数,该函数接收一个字符串类型的IP地址作为参数,然后使用split方法按点分隔IP,接着遍历这些部分并将其转换为长整型,最后通过位移运算将各部分组合成一个Long型数值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Spark的将IP转换为Long型的方法

ip格式

192.168.111.4

转换方法

/**
    * 把IP转化为long类型的数据
    * @param ip
    * @return
    */
  def ip2Long(ip: String): Long = {
    val fragments = ip.split("[.]")
    var ipNum = 0L
    for (i <- 0 until fragments.length) {
      ipNum = fragments(i).toLong | ipNum << 8L
    }
    return ipNum
  }
import java.text.SimpleDateFormat import java.util.Date import org.apache.kafka.common.serialization.StringDeserializer import org.apache.kafka.common.TopicPartition import org.apache.spark.SparkConf import org.apache.spark.streaming.{Seconds, StreamingContext} import org.apache.spark.streaming.kafka010.{ConsumerStrategies, KafkaUtils, LocationStrategies} object KafkaStream { def main(args: Array[String]): Unit = { val kafkaParams = Map[String, Object]("bootstrap.servers" -> "127.0.0.1:9092", "group.id" -> "kafkaStream", "enable.auto.commit" -> "false", "key.deserializer" -> classOf[StringDeserializer], "value.deserializer" -> classOf[StringDeserializer], "group.id" -> "g1" ) val partition = new TopicPartition("test", 0) val list = List(partition) val offsets = Map(partition -> 0l) val conf = new SparkConf().setMaster("local[*]").setAppName("kafkaStream") /********** Begin **********/ //1.初始化StreamingContext,设置时间间隔为1S //2.使用 KafkaUtils 对象创建流,使用 Assign 订阅主题(Topic),上面已经为你定义好了 Topic列表:list,kafka参数:kafkaParams,偏移量:offsets /** * * 数据格式如下: * 100.143.124.29,1509116285000,'GET www/1 HTTP/1.0',https://www.baidu.com/s?wd=反叛的鲁鲁修,404 * 数据从左往右分别代表:用户IP、访问时间戳、起始URL及相关信息(访问方式,起始URL,http版本)、目标URL、状态码 * * * 原始数据的切割符为逗号,(英文逗号) * * 需求: * 1.将时间戳转换成规定时间(格式为:yyyy-MM-dd HH:mm:ss ) * 2.提取数据中的起始URL(切割符为空格) * 3.拼接结果数据,格式如下: * Ip:124.132.29.10,visitTime:2019-04-22 11:08:33,startUrl:www/2,targetUrl:https://search.yahoo.com/search?p=反叛的鲁鲁修,statusCode:200 * 4.判断rdd是否为空,如果为空,调用 ssc.stop(false, false)与sys.exit(0) 两个方法,反之将结果数据存储到mysql数据库中,调用DBUtils.add(line)即可, line:String */ //3.获取kafka流中的数据,进行清洗、转换(按照上面的需求) //4.判断rdd是否为空,如果为空,调用 ssc.stop(false, false)与sys.exit(0) 两个方法,反之将结果数据存储到mysql数据库中,调用DBUtils
最新发布
03-15
### 实现方案 以下是基于提供的引用内容和专业知识设计的一个完整的解决方案,涵盖了从Kafka主题订阅到数据处理再到MySQL存储的过程。 #### 1. 使用 `Assign` 策略订阅指定分区的主题 为了使用 `Assign` 策略订阅特定的分区,可以通过 `ConsumerStrategies.Assign()` 方法显式定义要消费的分区及其对应的起始偏移量。这种方式适用于需要精确控制哪些分区被消费的情况[^3]。 ```scala import org.apache.kafka.common.TopicPartition import org.apache.spark.streaming.kafka010.ConsumerStrategies.Subscribe import org.apache.spark.streaming.kafka010.LocationStrategies.PreferConsistent import org.apache.spark.streaming.kafka010._ import org.apache.spark.streaming.{Seconds, StreamingContext} import org.apache.spark.SparkConf val kafkaParams = Map[String, Object]( "bootstrap.servers" -> "localhost:9092", "key.deserializer" -> classOf[org.apache.kafka.common.serialization.StringDeserializer], "value.deserializer" -> classOf[org.apache.kafka.common.serialization.StringDeserializer], "group.id" -> "use_a_separate_group_id_for_each_stream", "auto.offset.reset" -> "earliest", "enable.auto.commit" -> (false: java.lang.Boolean) ) // 定义TopicPartitions val topicPartitions = Seq( new TopicPartition("test-topic", 0), new TopicPartition("test-topic", 1) ) // 起始偏移量 val fromOffsets = topicPartitions.map(tp => tp -> 0L).toMap // 创建DStream val stream = KafkaUtils.createDirectStream[ String, String ](ssc, PreferConsistent, Assign[String, String](topicPartitions, kafkaParams, fromOffsets)) ``` --- #### 2. 数据解析与清洗 对于流式数据的解析和清洗操作,可以利用 Spark 的 DStream 提供的操作接口完成时间戳转换、URL 提取等任务。 ```scala stream.foreachRDD { rdd => val data = rdd.map(record => { val value = record.value() try { // 假设每条消息是一个JSON对象 import org.json4s._ import org.json4s.jackson.JsonMethods._ implicit val formats = DefaultFormats val json = parse(value) // 时间戳转换为字符串 val timestamp = (json \ "timestamp").extractOpt[Long].map(_.toString).getOrElse("") // URL提取 val url = (json \ "url").extractOpt[String].getOrElse("") // 结果组装 s"$timestamp,$url" } catch { case e: Exception => "" } }) // 进行非空过滤 val cleanedData = data.filter(!_.isEmpty()) // 将清理后的数据保存至MySQL saveToMySQL(cleanedData.collect().toList) } def saveToMySQL(dataList: List[String]): Unit = { dataList.foreach(row => { // 解析row中的字段并执行SQL插入语句 val Array(timestamp, url) = row.split(",") Class.forName("com.mysql.cj.jdbc.Driver") val connection = java.sql.DriverManager.getConnection("jdbc:mysql://localhost:3306/testdb?user=root&password=pass") val statement = connection.prepareStatement("INSERT INTO logs (timestamp, url) VALUES (?, ?)") statement.setString(1, timestamp) statement.setString(2, url) statement.executeUpdate() statement.close() connection.close() }) } ``` --- #### 3. MySQL 存储配置 在上述代码中,假设已经有一个名为 `logs` 的表用于存储处理后的数据。该表结构如下: ```sql CREATE TABLE logs ( id INT AUTO_INCREMENT PRIMARY KEY, timestamp VARCHAR(50), url TEXT ); ``` 需要注意的是,每次连接数据库可能会带来性能开销。因此,在实际生产环境中建议批量提交数据或将 JDBC 操作封装成更高效的工具类[^2]。 --- ### 总结 以上代码实现了以下几个功能: - **Kafka 主题订阅**:通过 `Assign` 策略指定了具体的分区和起始偏移量。 - **数据解析与清洗**:完成了 JSON 数据的时间戳转换、URL 提取以及结果组装。 - **MySQL 存储**:将清洗后的数据逐条或批量写入 MySQL 表中。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值