通过在 kdb 中的分区 table 中附加消息来重播 tplog 文件

Replay tplog file by appending messages in the partitioned table in kdb

我正在尝试通过附加消息将消息从 tp 日志直接重播到磁盘上的分区 table,因为与 tplog 大小相比我没有太多的主内存。

TpLog 如下:

q)9 2 sublist get `:/Users/uts/Desktop/repos/ktick/tick/sym2020.05.23
`upd `trade (,0D22:38:00.083960000;,`MSFT.O;,45.15104;,710)              
`upd `quote (,0D22:38:01.082882000;,`VOD.L;,341.2765;,341.3056;,732;,481)

我正在使用下面的 'upsert' 方法将这些 tplog 消息附加到分区 table 但它失败并在 upsert 上出现类型错误:

quote:([]time:`timespan$();sym:`symbol$();bid:`float$();ask:`float$();bsize:`int$();asize:`int$());
trade:([]time:`timespan$();sym:`symbol$();price:`float$();size:`int$());


`:/Users/uts/db/2020.05.23/quote/ set .Q.en[`:/Users/uts/db;]quote;
`:/Users/uts/db/2020.05.23/trade/ set .Q.en[`:/Users/uts/db;]trade;


upd:{[t;d]
    if[`trade~t;[show raze d;`:/Users/uts/db/2020.05.23/trade/ upsert .Q.en[`:/Users/uts/db;]enlist (cols trade)!raze d]];
    };

-11!`:/Users/uts/Desktop/repos/ktick/tick/sym2020.05.23

错误:

    'type
  [1]  upd:{[t;d]
    if[`trade~t;[show raze d;`:/Users/utsav/db/2020.05.23/trade/ upsert .Q.en[`:/Users/utsav/db;]enlist (cols trade)!raze d]];
                                                                 ^
    }

但是如果我尝试手动将消​​息附加到分区 table,它工作正常:

`:/Users/uts/db/2020.05.23/trade/ upsert .Q.en[`:/Users/uts/db;]enlist (cols trade)!raze (enlist 0D22:39:00.083960000;enlist `MSFT.O;enlist 45.15104; enlist 710)

不确定为什么 'upsert' 不能与 -11 一起在 upd 函数中工作!

如果有更好的方法(很可能必须有)在不使用太多主内存的情况下将 tplog 直接重播到磁盘,请分享(details/links)。

我不确定它是否能解决您的确切问题,但有一些建议:

  1. 您的代码假定每条 tickerplant 日志记录都对应一行。情况可能并非如此,因为许多 tickerplant 日志将在一次更新中记录多行。这意味着您的 enlist (cols trade)!raze d 代码不起作用(尽管我怀疑在这种情况下存在长度错误)。更通用的替代方法是使用:
$[0>type first d;enlist cols[trade]!d;flip cols[trade]!d]
  1. 您不应该尝试将 tickerplant 日志中的每条更新记录都写入磁盘 - 在如此短的 space 时间内,磁盘写入太多了。它效率低下,可能导致磁盘 I/O 限制。最好插入内存,直到 table 达到一定大小,然后批量写入并擦除 table。我建议像这样:
write:{`:/Users/uts/db/2020.05.23/trade/ upsert .Q.en[`:/Users/uts/db;value x];delete from x};
upd:{[t;d]
    if[`trade~t;t insert d];
    if[10000<count value t;write[t]];
    };

那么您的重播将如下所示:

-11!`:/Users/uts/Desktop/repos/ktick/tick/sym2020.05.23;
if[0<count trade;write[`trade]]; /need to write the leftovers
`sym`time xasc `:/Users/uts/db/2020.05.23/trade/;
@[`:/Users/uts/db/2020.05.23/trade/;`sym;`p#];