Kibana 대시보드에 새로 추가한 지표 필드가 안 보여서 확인하니 Elasticsearch 인덱스의 필드 수 상한을 넘어 있었다. index.mapping.total_fields.limit 이 기본 1000 이라는 것을 아무도 모르고 있었다.
Table of contents
Open Table of contents
증상 — 한도가 있다는 것을 몰랐다
필드를 계속 추가하면서 그것이 무한히 늘어날 수 있다고 전제하고 있었다. 어느 시점부터 새 문서가 Logstash 쪽에서 거부되는데 그 사실이 Kibana 화면에는 드러나지 않았다.
한도가 있다는 것 자체를 모르면 차 있다는 것도 모르고 왜 안 되는지도 못 찾는다. 그래서 GET /metrics-*/_mapping 으로 무엇이 그 한도를 차지하고 있는지부터 세어 봤다.
원인 — 한 종류가 차지하던 대부분
종류별로 세어 보니 회원별 필드가 대부분을 차지하고 있었다. member_1234.balance 처럼 회원마다 필드 이름을 만드는 방식이라 회원이 늘면 필드도 함께 늘었다. Elasticsearch 7.8 공식 문서가 매핑 폭발이라고 부르는 바로 그 형태였다.
이 방식으로는 언제 차느냐의 문제일 뿐 반드시 한도에 닿는다. 개별 정리가 아니라 만드는 방식을 바꿔야 하는 자리였다.
조치 — 대상별 필드와 태그
두 가지 방법이 있었다. total_fields.limit 을 10000 으로 올리는 것과, 필드 이름을 balance 하나로 두고 구분은 member_id 키워드 필드로 옮기는 것이다. 뒤쪽을 골랐다. 이유는 공식 문서가 상한을 올리면 메모리와 성능이 나빠진다고 적고 있고 올려도 언젠가는 또 차기 때문이다. 대신 대시보드의 시각화를 전부 다시 만드는 것을 감수했다. 수천 개 필드가 몇 개로 줄었다.
키워드 필드에도 카디널리티가 높으면 집계 비용이 커지므로 값이 무한히 늘어나는 식별자는 거기에도 안 넣었다. 회원별 상세는 지표가 아니라 로그에서 보게 갈랐다. 지표에 넣을 것과 로그에 남길 것을 나누는 것이 이 정리의 기준이 됐다.
안 쓰는 것과 정리 기준
Kibana 대시보드와 알림에서 실제로 참조하는 필드 이름을 뽑아 전체 _mapping 과 대조하니 안 쓰는 것이 천 개를 넘었다. 바로 지우지 않고 한동안 표시만 해 뒀는데 분기에 한 번 보는 것이 있을 수 있어서였다.
정리 기준은 오래 참조되지 않은 것과 키워드 필드로 대체 가능한 것과 값이 항상 같은 것 셋으로 정했다. 마지막이 의외로 많았고 만들어 놓고 값을 안 넣는 필드들이었다.
차기 전에 아는 것
_mapping 의 필드 수를 total_fields.limit 으로 나눈 사용률을 지표로 만들어 일정 비율을 넘으면 알리게 했다. 찬 뒤에 아는 것과 차기 전에 아는 것은 대응할 수 있는 폭이 다르다.
같은 종류의 한도가 더 있는지 찾아보니 알림 규칙과 대시보드 수와 Logstash 처리량과 ILM 보관 기간까지 여럿이었다. 각각 지금 얼마인지 확인해 문서에 적었고 알림 규칙도 거의 차 있어서 발동한 적 없는 것과 늘 발동해 아무도 안 보는 것을 정리했다.
정리
Elasticsearch에는 필드 수 상한이 있고 있다는 것 자체를 먼저 안다- 한도를 모르면 차 있다는 것도 왜 안 되는지도 모른다
- 무엇이 차지하는지 세면 한 종류가 대부분인 경우가 많다
- 대상마다 필드를 만들지 말고
member_id키워드로 구분한다 - 값이 무한히 느는 것은 키워드 집계에도 안 넣는다
- 지표에 넣을 것과 로그에 남길 것을 가른다
- 정리 기준에 값이 항상 같은 것도 넣는다
- 차기 전에 알리고 같은 종류의 한도를 전부 문서에 적는다