$30 off During Our Annual Pro Sale. View Details »

Druid 반정형 데이터 고군분투기

kakao
December 09, 2022

Druid 반정형 데이터 고군분투기

#Druid

Druid로 JSON 형태의 반정형 데이터 분석 기능을 개발한 경험을 공유합니다.

발표자 : philip.han
카카오에서 데이터엔지니어로 일하고 있는 필립입니다. 개발이 좋아 이 일을 시작했습니다. 현재는 메니징 업무가 많지만 항상 개발을 꿈꾸는 꿈나무입니다.

kakao

December 09, 2022
Tweet

More Decks by kakao

Other Decks in Programming

Transcript

  1. 한승후 philip.han


    카카오
    Druid 반정형 데이터 고군분투기
    if(kakao)2022
    Copyright 2022. Kakao Corp. All rights reserved. Redistribution or public display is not permitted without written permission from Kakao.

    View Slide

  2. 반정형 데이터 다루기


    프로토타이핑


    성능개선


    Nested Complex Column

    View Slide

  3. 반정형 데이터 다루기

    View Slide

  4. w
    {


    "timestamp":"2018-01-01T01:01:35Z",


    "srcIP":"1.1.1.1",


    "dstIP":"2.2.2.2",


    "packets":20


    }


    timestamp 2018-01-01T01:01:35Z
    srcIP 1.1.1.1
    dstIP 2.2.2.2
    packets 20

    View Slide

  5. {


    "timestamp":"2018-01-01T01:01:35Z",


    ”custom_data”:


    {


    "srcIP":"1.1.1.1",


    "dstIP":"2.2.2.2",


    "packets":20


    }


    }


    fl
    attening
    timestamp 2018-01-01T01:01:35Z
    custom_data.srcIP 1.1.1.1
    custom_data.dstIP 2.2.2.2
    custom_data.packets 20

    View Slide

  6. {


    "timestamp":"2018-01-01T01:01:35Z",


    ”custom_data”:


    {


    "srcIP":"1.1.1.1",


    "dstIP":"2.2.2.2",


    "packets":20


    }


    }


    {


    "timestamp":"2018-01-01T01:01:51Z",


    ”custom_data”:


    {


    "id":123,


    "order_id":456,


    "item":"ryan"


    }


    }


    timestamp
    2018-01-01
    T01:01:35Z
    2018-01-01
    T01:01:51Z
    custom_data.srcIP 1.1.1.1 null
    custom_data.dstIP 2.2.2.2 null
    custom_data.packets 20 null
    custom_data.id null 123
    custom_data.order_id null 456
    custom_data.item null ryan
    fl
    attening

    View Slide

  7. 데이터의


    변화
    쿼리


    변경
    스키마


    변경
    시각화 툴


    수정 필요
    데이터와


    시스템의 강결합

    View Slide

  8. {


    "timestamp":"2018-01-01T01:01:35Z",


    ”custom_data”:


    {


    "srcIP":"1.1.1.1",


    "dstIP":"2.2.2.2",


    "packets":20


    }


    }


    {


    "timestamp":"2018-01-01T01:01:51Z",


    ”custom_data”:


    {


    "id":123,


    "order_id":456,


    "item":"ryan"


    }


    }


    timestamp 2018-01-01T01:01:35Z 2018-01-01T01:01:51Z
    custom_data
    {
    "srcIP":"1.1.1.1",
    "dstIP":"2.2.2.2",
    "packets":20
    }
    {
    ”id":123,
    ”order_id":456,
    ”item":”ryan”
    }

    View Slide

  9. 프로토타입

    View Slide

  10. class JSONPathExtractStringFunc implements Function


    {


    @Override


    public ExprEval apply(List args, Expr.ObjectBinding bindings)


    {


    final String arg = args.get(0).eval(bindings).asString();


    Object result =


    JSON_PARSER_CONTEXT.parse(arg).read(args.get(1).eval(bindings).asString());


    if (result == null) {


    return ExprEval.of(null);


    }


    return ExprEval.of((String) result);


    }


    }


    Json을 String 형태로 저장


    JsonPath 라이브러리로 분석

    View Slide

  11. Json을 String 형태로 저장


    JsonPath 라이브러리로 분석
    class JSONPathExtractStringFunc implements Function


    {


    @Override


    public ExprEval apply(List args, Expr.ObjectBinding bindings)


    {


    final String arg = args.get(0).eval(bindings).asString();


    Object result =


    JSON_PARSER_CONTEXT.parse(arg).read(args.get(1).eval(bindings).asString());


    if (result == null) {


    return ExprEval.of(null);


    }


    return ExprEval.of((String) result);


    }


    }


    View Slide

  12. Json을 String 형태로 저장


    JsonPath 라이브러리로 분석
    class JSONPathExtractStringFunc implements Function


    {


    @Override


    public ExprEval apply(List args, Expr.ObjectBinding bindings)


    {


    final String arg = args.get(0).eval(bindings).asString();


    Object result =


    JSON_PARSER_CONTEXT.parse(arg).read(args.get(1).eval(bindings).asString());


    if (result == null) {


    return ExprEval.of(null);


    }


    return ExprEval.of((String) result);


    }


    }


    View Slide

  13. Simple Schema
    Column name Data type
    __time Timestamp
    custom_data Varchar
    Column name Data type
    __time Timestamp
    custom_data.srcIP Varchar
    custom_data.dstIP Varchar
    custom_data.packets Varchar
    custom_data.id Long
    custom_data.order_id Long
    custom_data.item Varchar

    View Slide

  14. Simple Query
    SELECT jsonpath_extract_string(custom_data, ) FROM logs
    SELECT custom_data.srcIP FROM logs


    SELECT custom_data.dstIP FROM logs


    SELECT custom_data.packets FROM logs


    SELECT custom_data.id FROM logs


    SELECT custom_data.item FROM logs

    View Slide

  15. Column name Data type
    __time Timestamp
    custom_data Varchar
    SELECT jsonpath_extract_string(custom_data, ) FROM logs

    View Slide

  16. 데이터의


    변화
    쿼리


    변경
    스키마


    변경
    시각화 툴


    수정 필요
    데이터와


    시스템의 강결합

    View Slide

  17. 데이터의


    변화
    쿼리


    변경 없음
    스키마


    변경 없음
    시각화 툴


    수정 불필요
    느슨한 결합

    View Slide

  18. 0
    2604
    5208
    JsonPath
    성능 이슈
    장비 스펙 core 10, mem 32GB, SSD
    데이터 1,000,000 rows
    (ms)

    View Slide

  19. 성능 개선

    View Slide

  20. 우리가 필요한 기능
    JsonPath What we need
    Single Value Extraction O O
    Nested JSON Object Handling O O
    Polymorphic Type Handling O X
    Operators O X
    Functions O X
    Filter Operators O X
    Predicates O X

    View Slide

  21. 공간 복잡도 O(1)
    시간 복잡도 O(n)
    json_extract_string(


    ‘{“session”:123,”action”:”click”}',


    “action”


    )


    json_extract_string(


    '{“session”:123, "event":{”id”:1104, “status":"N"}',


    ["event", “status"]


    )
    필수 기능만 제공하는 JSON 파서 작성

    View Slide

  22. 공간 복잡도 O(1)
    시간 복잡도 O(n)
    필수 기능만 제공하는 JSON 파서 작성
    json_extract_string(


    ‘{“session”:123,”action”:”click”}',


    “action”


    )


    json_extract_string(


    '{“session”:123, "event":{”id”:1104, “status":"N"}',


    ["event", “status"]


    )

    View Slide

  23. 공간 복잡도 O(1)
    시간 복잡도 O(n)
    필수 기능만 제공하는 JSON 파서 작성
    json_extract_string(


    ‘{“session”:123,”action”:”click”}',


    “action”


    )


    json_extract_string(


    '{“session”:123, "event":{”id”:1104, “status":"N"}',


    ["event", “status"]


    )

    View Slide

  24. 공간 복잡도 O(1)
    시간 복잡도 O(n)
    필수 기능만 제공하는 JSON 파서 작성
    json_extract_string(


    ‘{“session”:123,”action”:”click”}',


    “action”


    )


    json_extract_string(


    '{“session”:123, "event":{”id”:1104, “status":"N"}',


    ["event", “status"]


    )

    View Slide

  25. 성능 비교
    0
    1200
    2400
    3600
    4800
    6000
    JsonPath
    FastJson
    장비 스펙 core 10, mem 32GB, SSD
    데이터 1,000,000 rows
    (ms)

    View Slide

  26. Key index using multi value dimension
    JSON Key index
    JSON rows
    JSON rows
    Filter rows
    key 추출
    JSON function
    Values

    View Slide

  27. 성능 비교
    0
    1200
    2400
    3600
    4800
    6000
    JsonPath
    FastJson
    JsonPath
    FastJson
    key index
    장비 스펙 core 10, mem 32GB, SSD
    데이터 1,000,000 rows
    (ms)

    View Slide

  28. Nested Complex Column

    View Slide

  29. Field List
    {"event":{”id”:1104, “status":"N"}
    .id .status Type List Long String
    .id Local Dictionary
    0 1 2 …
    Bitmap Index
    Value Column
    0
    1
    2

    0
    0
    1

    .status Local Dictionary
    NULL “E” “N” …
    Bitmap Index
    Value Column
    NULL
    “E”
    “N”

    0
    0
    1

    View Slide

  30. Field List .id .status Type List Long String
    .id Local Dictionary
    0 1 2 …
    Bitmap Index
    Value Column
    0
    1
    2

    0
    0
    1

    .status Local Dictionary
    NULL “E” “N” …
    Bitmap Index
    Value Column
    NULL
    “E”
    “N”

    0
    0
    1

    {"event":{”id”:1104, “status":"N"}

    View Slide

  31. 성능 비교
    0
    1200
    2400
    3600
    4800
    6000
    JsonPath
    FastJson
    N
    estedC
    olum
    n
    JsonPath
    FastJson
    N
    estedC
    olum
    n
    key index
    장비 스펙 core 10, mem 32GB, SSD
    데이터 1,000,000 rows
    (ms)

    View Slide

  32. 성능 비교 - Ingestion
    0
    34000
    68000
    102000
    136000
    170000
    FastJson
    N
    estedC
    olum
    n
    장비 스펙 core 10, mem 32GB, SSD
    데이터 1,000,000 rows
    (ms)

    View Slide

  33. FastJson NestedColumn
    Rich Functionality ★ ★★
    Key Index ★ ★★
    Read Performance ★ ★★
    Write Performance ★★ ★

    View Slide

  34. 참고 문헌
    1) https:/
    /github.com/apache/druid/pull/11467


    2) https:/
    /github.com/apache/druid/issues/12695


    3) https:/
    /github.com/json
    -
    path/JsonPath

    View Slide

  35. E.O.D

    View Slide