时间序列数据库KDB 与Java结合使用介绍 -- 1 KDB Java代码解读

KDB是Kx System开发的时间序列数据库,通常用于处理交易行情相关数据。具体介绍可以参考:https://en.wikipedia.org/wiki/Kdb%2B。

在我们的计价系统中使用kdb来存储计价数据,由于KDB是基于Q语言的,我们的计价系统是Java写的,所以使用了KDB提供的Java API。

KDB的Java实现在KDB源代码有下载。其中最核心的是c.java,我们先来看看它的实现。

c.java的使用需要通过创建一个新的c对象,以c的构造函数为例:

public C(final String h, final int p, final String u, final boolean useTLS)
            throws KException, IOException {
        B = new byte[2 + C.ns(u)];
        s = new Socket(h, p);
        if (useTLS) {
            s = ((SSLSocketFactory) SSLSocketFactory.getDefault())
                    .createSocket(s, h, p, true);
            ((SSLSocket) s).startHandshake();
        }
        io(s);
        J = 0;
        w(u + "\3");
        o.write(B);
        if (1 != i.read(B, 0, 1)) {
            close();
            B = new byte[1 + C.ns(u)];
            io(new Socket(h, p));
            J = 0;
            w(u);
            o.write(B);
            if (1 != i.read(B, 0, 1)) {
                close();
                throw new KException("access");
            }
        }
        vt = Math.min(B[0], 3);
    }

它通过参数kdb host: h,kdb port: p,kdb user&pass: u 以及是否使用安全传输: useTLS和远程kdb服务器进行通信,建立连接并且登陆,通常u是由username:password的形式传输。可以看到 通过socket给kdb传输数据。

 void io(final Socket x) throws IOException {
        s = x;
        s.setTcpNoDelay(true);
        {
            final InetAddress a = s.getInetAddress();
            l = a.isAnyLocalAddress() || a.isLoopbackAddress();
        }
        i = new DataInputStream(s.getInputStream());
        o = s.getOutputStream();
        s.setKeepAlive(true);
    }

那么一般使用什么函数往kdb里面插入数据呢?这里有2种实现,同步(public Object k(String s) throws KException, IOException)和异步(public void ks(String s) throws IOException),同步异步还有重载方法直接写入Object对象,我们系统写入的是完整的计价数据,所以必须先自己打包成String。同步和异步的实现差别就在于同步在往Socket写入数据后会等待kdb服务器返回结果。

      public void ks(final String s) throws IOException {
        w(0, cs(s));
    }
    public synchronized Object k(final Object x) throws KException, IOException {
        w(1, x);
        return k();
    }


    public Object k(final String s) throws KException, IOException {
        return k(cs(s));
    }
      protected void w(final int i, final Object x) throws IOException {
        final int n = nx(x) + 8;
        synchronized (o) {
            B = new byte[n];
            B[0] = 0;
            B[1] = (byte) i;
            J = 4;
            w(n);
            w(x);
            if (zip && J > 2000 && !l) {
                z();
            }
            o.write(B, 0, J);
        }
    }

这里有一点非常值得注意,这些方法的执行是同步的!!!在最开始我们的实现中,使用了多线程往kdb写入数据,而Connection我们只使用了一个C实例,这样意义就不是很大了。在我们想对实现做修改的时候,和kdb服务端维护人员沟通,发现kdb默认的实现就是单线程写入的,只支持多线程查询,单线程写入。所以我们改变多线程变成单线程,后面再说说相关实现细节。

single-thread which requires positive number of port
multi-thread which requires negative number of port


下一篇将给出一个简单的写使用案例。



你可能感兴趣的:(Java)