前面文章介紹過流數據輸入速率要和處理能力相匹配,短時數據爆發由內部緩衝隊列來緩衝。如果確實存在某個時間點持續數據爆發,可以考慮採取反壓限流的方法。
1. 示例操作步驟
(1)下載SODBASE Studio2.0.22(sp1)以上版本,解壓,打開configuration/global.properties,將引擎的緩衝隊列長度設的較小,作以下配置
maxqueuelength=100
warnqueuelength=20
(2)下載示例EPL模型backpress01.sod、backpress02.sod
backpress01功能:CPU滿負荷不停的產生模擬數據,打印到屏幕。因爲嚴格地講,屏幕打印的速度也是跟不上CPU滿負荷產生數據速度的。因此容易達到隊列報警值20。
backpress02功能:將system.sys_warn的報警事件反接到backpress01的控制Socket端口上。
(3)打開SODBASE Studio,導入backpress01.sod、backpress02.sod
先測試運行backpress02,再將backpress01也測試運行起來。
(4)結果輸出
可以看到如下的輸出結果,並且發現隔一段時間,數據就慢下來,這就是反壓限速的原因。
2. 工作原理
2.1可控制輸入適配器
上面示例能夠實現反壓限速,是因爲編寫backpress01的輸入適配器時,繼承了SODBASE CEP一類可控制輸入適配器。這類可控制輸入適配器,通過Socket監聽控制事件,並在接收到控制事件後調用回調函數callback(PrimitiveEvent e),在回調函數中可以讓輸入流sleep一段時間。
讀者要實現同樣的功能,只需集成實現com.sodbase.inputadaptor.controllable.ControllableInputAdaptorI類。前3個參數默認爲數據流名、控制監聽端口、控制監聽端口超時時間(ms)。讀者要添加參數,可以從第4個參數開始添加。示例中的輸入適配器代碼如下
public class ControllableTestInputAdaptor extends ControllableInputAdaptorI
{
private boolean running=true;
private long suspendtime=0;
@Override
public void setUp()
{
//必須調用super.setUp()啓動控制監聽端口
super.setUp();
}
@Override
public void callback(PrimitiveEvent primitiveEvent)
{
if(primitiveEvent.getAttributeValueType("cause").getValue().equals(Constants.causecode1))
suspendtime=5000;
}
@Override
public boolean isRunning()
{
return running;
}
@Override
public void stopInputStream()
{
//必須調用super.stopInputStream()關閉控制監聽端口
super.stopInputStream();
this.running=false;
}
public void run()
{
int count = 1;
while (running)
{
try
{
if(suspendtime>0)
{
Thread.sleep(suspendtime);
suspendtime=0;
}
}
catch (InterruptedException e)
{
e.printStackTrace();
}
PrimitiveEvent primitiveEvent = new PrimitiveEvent();
primitiveEvent.getAttributeMap().put("id", new ValueType(String.valueOf(count),"string"));
count++;
Date d = new Date();
long time = d.getTime();
primitiveEvent.setStart_ts(time);
primitiveEvent.setEnd_ts(time);
this.putEventToStream(primitiveEvent);
}
}
}
2.2 系統報警事件
SODBASE CEP允許通過warnqueuelength配置緩衝隊列長度的報警長度,可針對報警採取一些運維管理措施。如果不配置,默認爲最大緩衝隊列長度maxqueuelength的80%。
system.sys_warn和system.sys_error是系統內置報警流,通常會含3個字段
(1)cause:報警和報錯的原因
(2)queryname:引起報警和報錯的EPL語句名稱
(3)message:消息提示
如cause=’warnqueuelengthexceeded’時,即超過了緩衝隊列的報警閾值。
2.3 注意事項
(1)多用戶環境下,報警流queryname字段會加前綴"用戶名."。
(2)設計系統時,不要過度依賴反壓限速功能,因爲反壓限速會增加輸入端負載,也會給系統帶來新的問題。正確方式是在系統架構初期,採用模擬數據和最大輸入速率配置好緩衝區大小,設計好處理方式並留出餘量,讓處理能力和輸入速率相匹配。
SODBASE CEP用於輕鬆、高效實施數據監測、監控類、實時交易類項目。EPL語法見SODSQL寫法與示例。圖形化建模請使用SODBASE
Studio。嵌入式方式編程參見運行第一個EPL例子。與Storm集成參見EPL與Storm集成。緩存擴展參見與分佈式緩存集成。