頻繁寫入vertica,可能導致ROS和WOS錯誤。如下:
java.sql.SQLTransientException: [Vertica][VJDBC](5065) ERROR: Too many ROS containers exist for the following projections:
logs.op_logs_req_super (limit = 16384, ROS files = 16384, DV files = 0, new files = 16)
at com.vertica.util.ServerErrorData.buildException(Unknown Source)
at com.vertica.dataengine.VQueryExecutor.readCopyStartResponse(Unknown Source)
at com.vertica.dataengine.VQueryExecutor.handleExecuteResponse(Unknown Source)
at com.vertica.dataengine.VQueryExecutor.execute(Unknown Source)
at com.vertica.jdbc.common.SPreparedStatement.executeBatch(Unknown Source)
at com.vertica.jdbc.VerticaJdbc4PreparedStatementImpl.executeBatch(Unknown Source)
以下是原因,以及解決方案。
轉載:
碰到找個問題就不得不說說Vertica的儲存機制了。Vertica在預設情況下會把新寫入的資料寫入到WOS(寫最佳化)中,然後根據一定的條件(比如說一定的時間週期)再把WOS中的資料寫入到ROS(讀最佳化)中,這時ROS有可能很多都是很小資料塊的碎片,這是Vertica會在一定的時間週期後把這些ROS資料塊合併成大的ROS檔案。
這裡把資料從WOS寫入到ROS的過程Vertica管它叫MoveOut操作,而把零散的ROS合併成大的ROS的過程Vertica管它叫MergeOut操作。
好了,現在來看看我們的問題吧。錯誤裡報的是ROS太多,那可能的原因是
1. WOS寫ROS太多,這個原因的原因很大的可能是每次insert/update的資料集太小,導致生成的碎片太多。
2. ROS太多,而配置的MoveOut和MergeOut的時間間隔太長,導致來不及做MoveOut和MergeOut。
好吧來看看我的應用吧
1. 針對第一個可能的原因,確實是我們的應用的需求的問題,這個目前來說我們沒法改變。
2. 對於第二個可能的原因,我們查了一下Vertica的資料,在Vertica中預設的MergeOutInterval是600,MoveOutInterval是300。這兩個引數可以透過下面的命令來檢視
SELECT GET_CONFIG_PARAMETER('MoveOutInterval');
SELECT GET_CONFIG_PARAMETER('MergeOutInterval');
由於我們的應用本身會產生很多的ROS碎片,所以我們想到了是不是可以透過減小MoveOut和MergeOut的Interval來讓Vertica儘快的做MoveOut和MergeOut。因此我們修改了Vertica的引數
SELECT SET_CONFIG_PARAMETER('MoveOutInterval', 60);
SELECT SET_CONFIG_PARAMETER('MergeOutInterval', 30);
在修改了這兩個引數以後,我們的應用確實在執行了很長時間後都沒有再出現上面的問題了。
---------------------
後來再次出現這個問題,修改連線池引數解決了問題:
ALTER RESOURCE POOL TM MEMORYSIZE '4G' PLANNEDCONCURRENCY 6 MAXCONCURRENCY 10;
-----------------------
其實關於這個問題,還有幾個引數可以調節,具體資料可以參考: