KDB Tickerplant架构拆分RDB订阅表时遭遇'type'错误求助
KDB Tickerplant RDB订阅表切换后'type'错误排查
错误场景
当前采用1个Tickerplant、1个RDB、1个HDB的架构,因原RDB处理速度慢导致Tickerplant内存持续增长,计划拆分表到2个RDB中。将RDB订阅trade表的语句改为订阅account_balances表后,触发如下'type'错误:
'type [3] /home/naseef/q/l64/tick/rdb.q:31: .u.rep:{(.[;();:;].)each x; ^ if[null first y;:()];
错误原因
- Tickerplant未注册目标表Schema:切换订阅表后,若Tickerplant进程中未预定义或注册
account_balances表的结构,返回给RDB的订阅响应(即.u.rep的参数x)会包含非法或空的Schema数据,导致(.[;();:;].)each x执行赋值操作时因类型不匹配报错。 .u.rep函数硬编码操作无容错:原函数中直接执行select by sym, asset from account_balances,若订阅后RDB尚未收到任何数据,account_balances表不存在,会触发类型错误(虽错误行指向Schema赋值,但表不存在的问题可能连锁触发异常)。- 订阅响应结构异常:若Tickerplant未发布
account_balances表的更新,订阅返回的x结构不符合预期(比如Schema部分为null),导致遍历赋值时出错。
解决方法
1. 确认Tickerplant端的表结构注册
检查Tickerplant进程的代码,确保account_balances表的结构已正确注册:
- 若使用静态Schema,需在Tickerplant启动时预定义表结构,例如:
account_balances:([]sym:`symbol$();asset:`symbol$();balance:`float$();ts:`timestamp$()) .u.tables:`account_balances`trade / 确保集合中包含目标表 - 若为动态Schema,需确认Tickerplant已通过
.u.init或其他方式加载了account_balances的结构。
2. 验证订阅响应的合法性
在RDB中单独测试订阅请求,确认返回值结构正常:
h:hopen `$":",.u.x 0 / 连接Tickerplant res:h"(.u.sub[`account_balances;`];`.u `i`L)" / 发送订阅请求 res / 查看返回的(Schema; 日志数据)结构
确保返回的res[0]是合法的表定义(而非null或错误类型),res[1]是正常的日志数据结构。
3. 修复.u.rep函数的容错逻辑
修改.u.rep函数,增加参数校验和表存在判断,避免空值或无表时出错:
.u.rep:{ / 先校验参数x的合法性 if[null x or 0=count x;:()]; (.[;();:;].)each x; if[null first y;:()]; -11!y; .Q.gc[]; / 仅当表存在时执行聚合操作 if[`account_balances in tables`.; `account_balances set select by sym, asset from account_balances; ]; `upd set (upsert); system "cd ",1_-10_string first reverse y };
4. 在RDB预定义目标表结构
若Tickerplant为动态发布表,可在RDB脚本开头预定义account_balances的表结构,确保订阅后能正常接收数据:
/ 预定义account_balances表结构,字段需与Tickerplant端完全一致 account_balances:([]sym:`symbol$();asset:`symbol$();balance:`float$();ts:`timestamp$())
内容的提问来源于stack exchange,提问作者works
相关产品推荐
相关产品推荐

