veluxer62 / veluxer62.github.io

veluxer's blog
http://veluxer62.github.io
MIT License
1 stars 0 forks source link

4월 개발일지 #530

Closed veluxer62 closed 3 years ago

veluxer62 commented 3 years ago

git merge 오류 발생시 해결방법

error: You have not concluded your merge (MERGE_HEAD exists).

https://gutmate.github.io/2018/04/18/git-pull-fail/

veluxer62 commented 3 years ago

postgresql explain

https://postgresql.kr/docs/9.6/sql-explain.html

veluxer62 commented 3 years ago

git ignore 파일들

https://github.com/github/gitignore

veluxer62 commented 3 years ago

괜찮은 사이트

https://developmentgeek.com/

veluxer62 commented 3 years ago

bean validation

https://beanvalidation.org/

veluxer62 commented 3 years ago

TDD

veluxer62 commented 3 years ago

ElasticSearch에서 aggs 쓰려면 (group by) 해당 컬럼의 타입이 text가 아니라 keyword여야 한다. 또는 "fieldData"를 추가하면 됨

https://www.elastic.co/guide/en/elasticsearch/reference/current/text.html#fielddata-mapping-param

하지만 text에 fieldData를 붙이는거는 성능적으로 좋지 않으며 keyword를 쓰는것을 권장한다. 집계나 정렬을 쓰려명 결국 동일한 필드를 다른역할로써 다시 만들거나 해야함

veluxer62 commented 3 years ago

ES aggregation group by 한 전체 건수 가져오는 방법 cardinality 사용하면됨

{
"aggs": {
    "byCategory": {
      "terms": {
        "field": "category_keyword.keyword"
      }
    },
    "total": {
      "cardinality": {
        "field": "category_keyword.keyword"
      }
    }
  }
}
"aggregations" : {
    "total" : {
      "value" : 3
    },
    "byCategory" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [
        {
          "key" : "음식물",
          "doc_count" : 2
        },
        {
          "key" : "음식",
          "doc_count" : 1
        },
        {
          "key" : "음식집",
          "doc_count" : 1
        }
      ]
    }
veluxer62 commented 3 years ago

paging하려면 아래와 같이

GET _search
{
  "query": {
    "match": {
      "category": "음식"
    }
  },
  "size": 0, 
  "_source": false, 
  "aggs": {
    "byCategory": {
      "terms": {
        "field": "category_keyword",
        "size": 10
      },
      "aggs": {
        "paging": {
          "bucket_sort": {
            "from": 0,
            "size": 10
          }
        }
      }
    },
    "total": {
      "cardinality": {
        "field": "category_keyword"
      }
    }
  }
}
veluxer62 commented 3 years ago

python 의 __init____all__

https://nesoy.github.io/articles/2018-07/Python-init-all

veluxer62 commented 3 years ago

python list comprehension 좋네

이게 성능적으로도 좋은데 python은 object가 정의되면 모든 서브 object를 다가지고 오는데 메모리 부하가 심하다 하지만 for문안에서 정의하면 필요한것만 사용하기 때문에 성능적으로 좋다

이거 레퍼런스를 좀 찾아봐야겟군

veluxer62 commented 3 years ago

elastic search

term과 match의 차이

https://m.blog.naver.com/PostView.nhn?blogId=rhkrehduq&logNo=221341623301&proxyReferer=https:%2F%2Fwww.google.com%2F

veluxer62 commented 3 years ago

pycharm에서 pytest 세팅 방법

  1. settings -> python integrated tools -> default test runner: pytest로 설정
  2. edit configuration -> edit: configuration templates.. -> python tests -> pytest 템플릿 선택 2-1. working directory를 Project root로 설정 (option) 환경변수가 있다면 environment variables를 추가a
veluxer62 commented 3 years ago

elastic search

그룹핑 유사도 정렬

query 사용 시 tokenizer의 유사도에 따라 index가 나오지만 aggs를 쓰는 순간 정렬이 중복개수순으로 정렬이 된다. 이런경우 유사도에 따라서 정렬을 할 수 있지 않을까 하는 생각이 들었는데 grouping 시 유사도를 max값을 추출하고 해당 max값을 기준으로 정렬을 하면되도록 하니 잘되었다. sum이 아니라 max를 한 이유는 중복개수가 많은것이 상위로 노출이 되는것을 방지하기 위해서

GET _search
{
  "query": { "match": { "name": "E2E-품목명" } }, 
  "aggs": {
    "data": {
      "terms": { 
        "field": "name_keyword", 
        "size": 2147483647,
        "order": {
          "maxScore": "desc"
        }
      },
      "aggs": { 
        "paging": { 
          "bucket_sort": {
            "from": 0, "size": 10 
          } 
        },
        "maxScore": {
          "max": {
            "script": {
              "source": "_score"
            }
          }
        }
      }
    },
    "total": { "cardinality": { "field": "name_keyword" } }
  }
}
veluxer62 commented 3 years ago

table 정보

Table "public.parents"
Column    | Type | Collation | Nullable | Default
-------------+------+-----------+----------+---------
id          | uuid |           | not null |
description | text |           | not null |
Indexes:
 "parents_pk" PRIMARY KEY, btree (id)
Referenced by:
 TABLE "children" CONSTRAINT "children_fk" FOREIGN KEY (parent_id) REFERENCES parents(id)

 Table "public.children"
 Column    | Type | Collation | Nullable | Default
-------------+------+-----------+----------+---------
id          | uuid |           | not null |
parent_id   | uuid |           | not null |
description | text |           | not null |
Indexes:
  "children_pk" PRIMARY KEY, btree (id)
  "children_parent_id_idx" btree (parent_id)
Foreign-key constraints:
  "children_fk" FOREIGN KEY (parent_id) REFERENCES parents(id) 

실행계획

parent 데이터 10개정도 생성

insert into parents select gen_random_uuid(), md5(a::text) as description from  generate_series(1, 2) a;

children 데이터 100만개 정도 생성 (10만개씩 10번 반복.. parent_id를 고루 분포시키기 위해)

insert into children 
select 
gen_random_uuid(), 
(
SELECT
    id
FROM
    parents
ORDER BY
    RANDOM()
limit 1
) as parent_id,
md5(a::text) as description from  generate_series(1, 100000) a;

검색을 위한 parent, children 데이터 추가 생성

insert into parents select gen_random_uuid(), md5(a::text) as description from  generate_series(1, 1) a;
insert into children 
select 
gen_random_uuid(), 
'8e4d92f7-f575-49a3-b78e-42b57ec2ad09'::uuid as parent_id,
md5(a::text) as description from  generate_series(1, 10) a;

단순 검색

explain analyse
select * from children 
where parent_id = '8e4d92f7-f575-49a3-b78e-42b57ec2ad09'::uuid

parent_id 인덱스 적용 전

Gather  (cost=1000.00..18554.49 rows=1 width=65) (actual time=49.475..52.574 rows=10 loops=1)
  Workers Planned: 2
  Workers Launched: 2
  ->  Parallel Seq Scan on children  (cost=0.00..17554.39 rows=1 width=65) (actual time=42.330..42.331 rows=3 loops=3)
        Filter: (parent_id = '8e4d92f7-f575-49a3-b78e-42b57ec2ad09'::uuid)
        Rows Removed by Filter: 333333
Planning Time: 0.129 ms
Execution Time: 52.620 ms

parent_id 인덱스 적용 후

Index Scan using children_parent_id_idx on children  (cost=0.42..7.51 rows=1 width=65) (actual time=0.047..0.049 rows=10 loops=1)
  Index Cond: (parent_id = '8e4d92f7-f575-49a3-b78e-42b57ec2ad09'::uuid)
Planning Time: 0.166 ms
Execution Time: 0.058 ms

Join 후 검색

explain analyse 
select * from parents p join children c on p.id = c.parent_id 
where c.parent_id = '8e4d92f7-f575-49a3-b78e-42b57ec2ad09'::uuid

parent_id 인덱스 적용 전

Nested Loop  (cost=1000.15..18562.67 rows=1 width=113) (actual time=35.480..38.994 rows=10 loops=1)
  ->  Index Scan using parents_pk on parents p  (cost=0.15..8.17 rows=1 width=48) (actual time=0.009..0.012 rows=1 loops=1)
        Index Cond: (id = '8e4d92f7-f575-49a3-b78e-42b57ec2ad09'::uuid)
  ->  Gather  (cost=1000.00..18554.49 rows=1 width=65) (actual time=35.467..38.975 rows=10 loops=1)
        Workers Planned: 2
        Workers Launched: 2
        ->  Parallel Seq Scan on children c  (cost=0.00..17554.39 rows=1 width=65) (actual time=32.607..32.608 rows=3 loops=3)
              Filter: (parent_id = '8e4d92f7-f575-49a3-b78e-42b57ec2ad09'::uuid)
              Rows Removed by Filter: 333333
Planning Time: 0.093 ms
Execution Time: 39.017 ms

parent_id 인덱스 적용 후

Nested Loop  (cost=0.58..15.69 rows=1 width=113) (actual time=0.016..0.023 rows=10 loops=1)
  ->  Index Scan using parents_pk on parents p  (cost=0.15..8.17 rows=1 width=48) (actual time=0.006..0.006 rows=1 loops=1)
        Index Cond: (id = '8e4d92f7-f575-49a3-b78e-42b57ec2ad09'::uuid)
  ->  Index Scan using children_parent_id_idx on children c  (cost=0.42..7.51 rows=1 width=65) (actual time=0.007..0.010 rows=10 loops=1)
        Index Cond: (parent_id = '8e4d92f7-f575-49a3-b78e-42b57ec2ad09'::uuid)
Planning Time: 0.140 ms
Execution Time: 0.043 ms

결론

검색 속도가 빠른이유는 ... 로컬에서 해당 테이블에 대한 데이터만 있기 때문으로 예상이됩니다. 중요한건 cost인데요, 인덱스 적용 전에는 1000.00 ~ 18554.49로 최소 1000에서 최대 18554개의 row를 스캔하는걸로 보입니다. 전채 건수보다 적은 이유는 Parallel Seq Scan과 PG의 데이터 저장 방식에 따라 성능적으로 이득을 가져가는 것으로 보이네요. 인덱스 적용 후에는 0.58 ~ 15.69로 최소 0에서 15개의 row를 스캔하는걸로 보입니다.

성능적으로 차이가 크게 나는 것으로 보여 인덱스를 따로 적용해야 할것으로 보이네요

전체적으로 적용하고 나중에 사용하지 않는 인덱스는 제거해야할거같음

출처

veluxer62 commented 3 years ago

매개변수(parameter)와 인수(arguments)는 혼용해서 사용되는 헷갈리는 용어이므로 잘 기억해 두자. 매개변수는 함수에 입력으로 전달된 값을 받는 변수를 의미하고 인수는 함수를 호출할 때 전달하는 입력값을 의미한다.

veluxer62 commented 3 years ago

https://github.com/securisec/chepy

veluxer62 commented 3 years ago

ES에서 grouping 함수 쓸대 버킷수 제한 확인하기

아래와 같은 오류를 만나면 버킷 설정때문임

{
  "took" : 20,
  "timed_out" : false,
  "_shards" : {
    "total" : 10,
    "successful" : 9,
    "skipped" : 0,
    "failed" : 1,
    "failures" : [
      {
        "shard" : 0,
        "index" : "cart_product_2021.04.21",
        "node" : "0f3zN3aKRaiAjis76RqNsg",
        "reason" : {
          "type" : "too_many_buckets_exception",
          "reason" : "Trying to create too many buckets. Must be less than or equal to: [10000] but was [10001]. This limit can be set by changing the [search.max_buckets] cluster level setting.",
          "max_buckets" : 10000
        }
      }
    ]
  },
  "hits" : {
    "total" : {
      "value" : 0,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
    "total" : {
      "value" : 0
    },
    "data" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [ ]
    }
  }
}

https://github.com/grafana/grafana/issues/17327

https://discuss.elastic.co/t/increasing-max-buckets-for-specific-visualizations/187390

veluxer62 commented 3 years ago

circleci 가 git hook을 못받는 현상이 발생했는데 unfollow 했다가 다시 follow 하니까 해결...

https://teratail.com/questions/319236

veluxer62 commented 3 years ago

파이썬으로 아키텍쳐 고민

veluxer62 commented 3 years ago

테라폼을 이용하여 RDS 사양 변경 시 바로 적용이 안되는 이슈가 있었다. 문서를 제대로 보지 않고 적용한게 문제긴 하지만 default로 즉시적용이 꺼져있어서였다.

https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_instance