kryo vs nokryo
背景
我今天突發奇想,說測一下kryo如果沒有註冊會咋樣,結果發現沒有註冊的Kryo性能低於直接使用java.io.Serializable
讀取速度
源數據: 42903237條記錄 907M
format | time / s |
---|---|
kryo | 134.341 |
java.io.Serializable | 150.878 |
kryoWithNoRegister | 165.701 |
存儲成本
spark task : 122
format | task/no space |
---|---|
kryo | all-pass |
java.io.Serializable | 47 |
KryoWithNoRegister | 15 |
在這個測試類一共有122個task,用kryo在全程都沒出現空間不足,如果沒使用註冊,不到20個task就出現了內存不足,在完全不使用kryo的情況下大概會在50個task的時候出現
如何使用kryo
- 需要序列化的類繼承
java.io.Serializable
- 註冊類繼承
KryoRegistrator
並且註冊那些需要序列化的類 - 在
sparkConf
中設置spark.serializer
和spark.kryo.registrator
測試數據源:
1 \N 男 \N
2 \N 女 \N
3 \N 女 \N
4 \N 男 \N
5 \N 保密 \N
對應的case class
:
/**
* Created by todd.chen on 5/23/16.
* email : todd.chen@ximalaya.com
*/
case class UserInfo(id:Long,name:String,gender:String,thirdParty:String) extends java.io.Serializable
性能測試代碼
package com.ctao.test.kryo
import org.apache.spark.storage.StorageLevel
import org.apache.spark.{SparkConf, SparkContext}
/**
* Created by todd.chen on 5/23/16.
* email : todd.chen@ximalaya.com
*/
object KryoTest {
def main(args: Array[String]) {
val start = System.currentTimeMillis()
val conf = new SparkConf().setMaster("local[*]").setAppName("kryoTest")
.set("spark.serializer", "org.apache.spark.serializer.KryoSerializer")
.set("spark.kryo.registrator", "com.ctao.test.kryo.MyRegisterKryo")
val sc = new SparkContext(conf)
val userInfo = sc.textFile("/Users/cjuexuan/data/user_info").map(line ⇒
line.split("\t")).map(user ⇒ UserInfo(user(0).toLong, user(1), user(2), user(3)))
userInfo.persist(StorageLevel.MEMORY_AND_DISK_SER)
println(userInfo.count())
println(System.currentTimeMillis() - start)
sc.stop()
}
}
package com.ctao.test.kryo
import com.esotericsoftware.kryo.Kryo
import org.apache.spark.serializer.KryoRegistrator
/**
* Created by todd.chen on 5/23/16.
* email : todd.chen@ximalaya.com
*/
class MyRegisterKryo extends KryoRegistrator {
override def registerClasses(kryo: Kryo): Unit = {
kryo.register(classOf[UserInfo])
}
}
日誌整理類:
import org.apache.spark.{SparkConf, SparkContext}
/**
* Created by todd.chen on 5/23/16.
* email : todd.chen@ximalaya.com
*/
object FilterLog {
def main(args: Array[String]) {
val input = args(0)
val conf = new SparkConf().setMaster("local[*]").setAppName("filterLog")
val sc = new SparkContext(conf)
sc.textFile(input)
.map(_.split(" "))
.filter(_.length > 3)
.filter(x ⇒ x(3) == "MemoryStore:" || x(3) == "BlockManagerInfo:").map(_.mkString(" "))
.collect().foreach(println)
sc.stop()
}
}