Camus使用過程當中業務方反映從Kafka導入至HDFS中的數據有中文亂碼問題,且業務方確認寫入的數據編碼爲UTF-8,開始跟進。
問題重現:
(1)編寫代碼將帶有中文的字符串以編碼UTF-8寫入Kafka的某個Topic;
(2)將該Topic的數據經過Camus導入HDFS;
(3)查看HDFS中導入的文件數據;
確認有中文亂碼問題存在,與業務方無關。
(1)寫入
這是一個寫入的代碼片斷,ProducerRecord是以字符串的形式設置的,而ProducerRecord中的key和value會經過「key.serializer」和「value.serializer」被序列化,這其中就會有字符編碼問題,查看org.apache.kafka.common.serialization.StringSerializer的源碼:
而「encoding」的值來源於下面的代碼片斷:
也就是說「encoding」在沒有顯示設置的狀況下,默認就是「UTF8」。
(2)導入
經過查看Camus的相關配置文件,有兩個屬性須要注意:
從屬性名稱以及註釋能夠推斷出,這兩個屬性值均與數據的編碼、解碼相關,查看它們的源代碼。
com.linkedin.camus.etl.kafka.common.StringRecordWriterProvider
能夠看出,StringRecordWriterProvider使用的是系統的默認編碼,可能存在隱患。
com.linkedin.camus.etl.kafka.coders.KafkaStringMessageDecoder(DIP自主開發)
能夠看出,KafkaStringMessageDecoder使用的是系統的默認編碼,可能存在隱患。
綜上所述,業務方寫入時(默認)使用UTF-8編碼進行導入,若是咱們Hadoop集羣的某些節點編碼不是UTF-8就能夠出現中文亂碼問題(之前出現過相似的問題)。
解決方案:顯示設置上述兩個操做的編碼。
com.linkedin.camus.etl.kafka.common.StringRecordWriterProvider
com.linkedin.camus.etl.kafka.coders.KafkaStringMessageDecoder
編譯代碼以前,須要修改如下兩個地方:
./camus-schema-registry-avro/pom.xml
./pom.xml
不然編譯過程當中會出現如下異常:
編譯命令以下:
mvn clean package -Dmaven.test.skip=true
最終生成的部署包位於:dip_camus/camus-example/target/camus-example-0.1.0-SNAPSHOT-shaded.jar
測試命令以下:
sudo -u hdfs hadoop jar camus-example-0.1.0-SNAPSHOT-shaded.jar com.linkedin.camus.etl.kafka.CamusJob -P k1001_camus.properties
請驗證,中文正常顯示,問題解決。