logstash讀取Oracle導入到es中


產生背景:某天領導說需要將Oracle中的一些表導入到es中,於是就開始了.....

方案說明

  1. 人生苦短我用py,直接jdbc連接,批量讀取,存儲es輕輕松松?
  2. 干大數據的怎么能少的了spark或flink?一個離線批處理不就ok了?
  3. 既然目標端是es那么還是用它自家產品logstash,輕松配置,無縫全量增量?

方案選擇

需求明確的領導,不是一個好領導,而不考慮需求實現的程序員不是一個好的數據搬運工。

嘗試方案一

  1. 百度查看了一下py和Oracle交互的模塊用到最多的有兩個,一個是cx_Oracle,一個是jaydebeapi

二者區別: cx_Oracle對py版本,系統環境版本依賴比較好,必須是門當戶對,如果你的es是在Windows下,那就更呵呵了,缺了VC++ 2014不行。而網上的答案千篇一律,裝環境都這么困難,直接next,jaydebeapi,這個模塊的連接方式類似於cx_Oracle,但是至少好安裝,直接下載tar.gz的源碼包,python setup.py install

  1. 環境ok了,開始打開pycharm,遠程連接服務器上的python環境,一切都很順利,但是寫着寫着,發現,沒有考慮到數據量很大咋整?得實現批量,數據中有大字段(clob)又咋整?又得判斷字段類型(前面已經提到是一些表,而非一張),判斷到是CLOB類型后還得讀取大字段轉為字符串類型...一來二去,我只是想遷移一些表的需求,結果活生生寫成了一個遷移工具的影子。於是果斷放棄。

嘗試方案二

  1. 經歷了方案一,那么同理只要是通過程序遷移避免不了數據量,更避免不了大字段的處理,想想方案二和方案一要經歷的過程一樣,只是選擇的語言和方式不同而已,果斷放棄。

嘗試方案三

  1. 基於之前已經安裝好input-jdbc插件的logstash,只需要解壓,寫一下配置文件即可,於是一個 增量 配置文件誕生了。
input {
        jdbc {
                #驅動包路徑
                jdbc_driver_library => "/home/risen/ojdbc.jar"
                #驅動類
                jdbc_driver_class => "Java::oracle.jdbc.driver.OracleDriver"
                #jdbc url
                jdbc_connection_string => "jdbc:oracle:thin:@ip:port:orcl"
                jdbc_user => "賬號"
                jdbc_password => "密碼"
                schedule => "* * * * *"
                statement => "select * from 表名"
                #增量標識字段名
                tracking_column => "主鍵"
                #是否使用字段值作為增量標識
                use_column_value => true
                #源表字段名導入ES后是否忽略大小寫
                lowercase_column_names=> false
                #分頁
                jdbc_paging_enabled => "true"
                #每頁數據量
                jdbc_page_size => "5000"
                #默認時區
                jdbc_default_timezone => "UTC"
        }
}
output{
        elasticsearch {
                hosts =>["ip:port"]
                index => "小寫表名"
                document_type => "小寫表名"
                document_id => "%{主鍵}"
        }
}
  1. 經過步驟一的完美配置后,開始啟動
bin/logstash -f ../oracle2es.conf  -w 3

正常運行不報錯,趕緊上es看看,它有沒有處理大字段,事實證明,還是"孿生兄弟"強,數據沒問題,還是增量同步,而且大字段也都被轉換為了字符串存儲。針對大數據量還可以通過-w指定線程數,同時還可以指定batch數量。

  1. 那么問題來了,這配置文件雖然好用,但是那可是200多張表呢?總不能導入一張修改一下配置文件吧,當然不能,接下來就需要 shell 登場了

!> logstash + shell 腳本有沒有搞頭?當然有

講過查詢,logstash的配置文件可以讀取外部設置的環境變量,那這個問題就妥了。

#!/bin/bash +x

#author:AmCoder

#設置logstash_path路徑
logstash_path=/home/risen/logstash-5.4.3

#設置logstash_conf_path路徑
logstash_conf_path=/home/risen/logstash-5.4.3/oracle2es.conf

if [ ! -n "$1" ] && [ ! -n "$2" ];then
        echo "Usage: sh oracle2es.sh 表名 主鍵"
        exit 1
fi

#由於logstash支持引用系統環境變量所以

##設置系統環境變量表名
export table_name=`echo $1 | tr 'a-z' 'A-Z'`

##設置系統環境變量表中的唯一主鍵
export unique_key=`echo $2 | tr 'a-z' 'A-Z'`

##設置索引名稱(表名轉小寫--es中的索引不能是大寫)
export es_index=`echo $table_name | tr 'A-Z' 'a-z'`

#啟動logstash並指定配置文件
$logstash_path/bin/logstash -f $logstash_conf_path -w 5

只需要修改logstash的安裝目錄和配置文件的目錄,然后將用到的公共變量(表名和主鍵)作為外部參數傳入即可了。當然之前的logstash的配置文件Oracle2es.conf也是需要修改為以下的(局部地方采用變量的方式):

input {
        jdbc {
                jdbc_driver_library => "/home/risen/ojdbc.jar"
                jdbc_driver_class => "Java::oracle.jdbc.driver.OracleDriver"
                jdbc_connection_string => "jdbc:oracle:thin:@ip:port:orcl"
                jdbc_user => "用戶名"
                jdbc_password => "密碼"
                schedule => "* * * * *"
                statement => "select * from ${table_name}"
                #增量標識字段名
                tracking_column => "${unique_key}"
                #是否使用字段值作為增量標識
                use_column_value => true
                #源表字段名導入ES后是否忽略大小寫
                lowercase_column_names=> false
                #分頁
                jdbc_paging_enabled => "true"
                #每頁數據量
                jdbc_page_size => "5000"
                #默認時區
                jdbc_default_timezone => "UTC"
        }
}
output{
        elasticsearch {
                hosts =>["ip:port"]
                index => "${es_index}"
                document_type => "${es_index}"
                document_id => "%{${unique_key}}"
        }
}

至此,問題基本已經解決了,剩下的就是你需要拿到200多張表的表名稱和主鍵了。大不了在寫個腳本套一層,當然也可以在上面的腳本中添加即可。總結一下,需要知道logstash可全量可增量,還可以引用外部變量,既可以多線程又可以指定分頁批次量。(但是,logstash目前還不支持國產服務器)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM