paust-team / paust-db

GNU General Public License v3.0
6 stars 5 forks source link

Survey query interface design of other NoSQL database #153

Closed dragon0170 closed 5 years ago

dragon0170 commented 5 years ago

ref: https://github.com/paust-team/paust-db/issues/145#issuecomment-475202619, #160

paust-db의 query interface를 timeseries database에 적절하게 설계하기위해 다른 NoSQL database의 query interface design을 우선 찾아보려고 합니다.

dragon0170 commented 5 years ago

Graph traversal을 위한 machine인 Apache TinkerPop의 Getting Started(http://tinkerpop.apache.org/docs/current/tutorials/getting-started/) 와 Gremlin Console(http://tinkerpop.apache.org/docs/current/tutorials/the-gremlin-console/) Document를 조사하면서 찾은 내용 중 paust-db에서 참고할만한 것들입니다.

elon0823 commented 5 years ago

저도 node 환경에서 REPL 을 통해서 실험한번해봤습니다. REPL 은 쉽게 implementation 가능한것같아요. 중요한건 인터페이스를 설계하는건데 모델 기반으로 설계를 해야할 것 같습니다. 지금은 httpclient상에서 각 인터페이스 구현부가있고 직접 호출하는 형태인데 이게 아닌 Query, Fetch, 등을 모델로 구현해서 내부의 interface를 통하여 iterator operation 을 구현하면 좋을듯하네요. 아직 어떤 인터페이스 들어갈지 정해진않아서 iterator operation 은 없지만 제 repo에 pdb-tester 에서도 진행하고있으니 같이 설계를 함 해봅시다.

dragon0170 commented 5 years ago

Column 기반 NoSQL database인 HBase의 HBase Shell(https://hbase.apache.org/book.html#shell) Document를 조사하면서 나온 것들 중 paust-db에서 참고할만한 것들입니다. HBase의 console은 Gremlin과는 달리 실제 query보다는 admin이 테스트나 관리를 위해 사용하는 관점을 위주로 만들어진 것 같습니다. 실제로 java application에서 import해서 사용하는 HBase의 코드 구현부를 살펴보면 paust-db Query Interface 구현에 도움이 될 것 같습니다.

================================

hbase(main):021:0> import java.util.Date hbase(main):022:0> Date.new(1218920189000).toString() => "Sat Aug 16 20:56:29 UTC 2008"

* HBase console scan interface는 아래와 같습니다.
> Scan a table; pass table name and optionally a dictionary of scanner
specifications. Scanner specifications may include one or more of:
TIMERANGE, FILTER, LIMIT, STARTROW, STOPROW, TIMESTAMP, MAXLENGTH,
or COLUMNS, CACHEIf no columns are specified, all columns will be scanned.
```shell
hbase> scan ‘.META.’, {COLUMNS => ‘info:regioninfo’}
hbase> scan ‘t1’, {COLUMNS => [‘c1’, ‘c2’], LIMIT => 10, STARTROW => ‘xyz’}
hbase> scan ‘t1’, {COLUMNS => ‘c1’, TIMERANGE => [1303668804, 1303668904]}
hbase> scan ‘t1’, {FILTER => “(PrefixFilter (‘row2’) AND
(QualifierFilter (>=, ‘binary:xyz’))) AND (TimestampsFilter ( 123, 456))”}
hbase> scan ‘t1’, {FILTER =>
org.apache.hadoop.hbase.filter.ColumnPaginationFilter.new(1, 0)}

=> Hbase::Table - t hbase(main):008 > t.put 'r', 'f', 'v' 0 row(s) in 0.0640 seconds hbase(main):009 > t.scan ROW COLUMN+CELL r column=f:, timestamp=1331865816290, value=v 1 row(s) in 0.0110 seconds hbase(main):010:0> t.describe DESCRIPTION ENABLED 't', {NAME => 'f', DATA_BLOCKENCODING => 'NONE', BLOOMFILTER => 'ROW', REPLICATION true SCOPE => '0', VERSIONS => '1', COMPRESSION => 'NONE', MIN_VERSIONS => '0', TTL => '2 147483647', KEEP_DELETED_CELLS => 'false', BLOCKSIZE => '65536', IN_MEMORY => 'false ', BLOCKCACHE => 'true'} 1 row(s) in 0.0210 seconds hbase(main):038:0> t.disable 0 row(s) in 6.2350 seconds hbase(main):039:0> t.drop 0 row(s) in 0.2340 seconds

==============================

hbase(main):011 > create 't','f' 0 row(s) in 1.2500 seconds

=> Hbase::Table - t hbase(main):012:0> tab = get_table 't' 0 row(s) in 0.0010 seconds

=> Hbase::Table - t hbase(main):013:0> tab.put 'r1' ,'f', 'v' 0 row(s) in 0.0100 seconds hbase(main):014:0> tab.scan ROW COLUMN+CELL r1 column=f:, timestamp=1378473876949, value=v 1 row(s) in 0.0240 seconds hbase(main):015:0>

dragon0170 commented 5 years ago

query 관련 내부 구조

HBase

https://hbase.apache.org/apidocs/org/apache/hadoop/hbase/client/package-summary.html#package.description 에 있는 Example API Usage 참고

  1. Scan object를 생성하고 탐색할 column family/qualifier, start key, end key, min/max timestamp, filter 등을 설정함.
  2. table.getScanner(Scan object) method로 ResultScanner object 생성. 얘가 Iterator 역할을 함.
  3. ResultScanner object에서 next() method를 통해 iterate하면서 Result object를 생성.
  4. Result Object에 실제 value 데이터가 있으며 value(), getValue(family, qualifier) 등의 method를 통해 사용 가능.

    TinkerPop Gremlin

    https://www.datastax.com/wp-content/uploads/2016/10/bytecode-to-execution.png 참고

  5. GraphTraversalSource object에서 V(), E()와 같은 method들로 GraphTraversal<S,E> object 생성.
    • GraphTraversal<S,E>는 Iterator를 상속받은 interface임. 따라서 iterate는 next()로 가능함.
  6. has(), values(), out()과 같은 method를 통해 존 GraphTraversal로부터 새로운 GraphTraversal 객체가 만들어짐.
    • 새로운 GraphTraversal 객체는 내부에서 addStep이라는 GraphTraversal method로 구성함. GraphTraversal 객체에 method의 이름과 똑같이 step을 하나하나씩 더해나가는 형태임.
    • step의 종류도 링크 사진의 machine code 부분에서 보듯이 여러가지임.
  7. has(), values(), out()과 같은 method들이 적용되면서 GraphTraversal의 E가 바뀜. 즉, iterator가 바뀜.