Go buger / jsonparser 를 사용 하여 반 직렬 화 성능 최적화
7643 단어 Golangelasticsearchgo.json
최근 에는 로그 시스템 ES 클 러 스 터 에서 데 이 터 를 내 보 내 고 압축 하여 텐 센트 클 라 우 드 에 업로드 하여 오프라인 콜 드 백업 데이터 로 사용 하 는 도 구 를 만 들 고 있 습 니 다.이 과정 에서 몇 가지 개성 에너지 문제 에 부 딪 혔 다.
그 중에서 도 Elasticsearch SDK 의 역 직렬 화 성능 이 병목 이 되 었 기 때문에 여기에 처리 방안 을 기록 합 니 다.
역 직렬 화 성능
olivere/elastic
는 자주 사용 하 는 기능 이 매우 강 한 Go Elasticsearch 클 라 이언 트 SDK 로 대부분의 Elasticsearch 의 요청 매개 변 수 를 구조 체 와 방법 으로 밀봉 하여 사용 하기 쉬 운 정도 가 매우 높다.요청 반환 값 을 처리 할 때 olivere/elastic
Go 내 에 만들어 진 json
라 이브 러 리 를 사용 하여 요청 결 과 를 대응 하 는 구조 체 로 역 정렬 하여 후속 작업 에 매우 편리 합 니 다.그러나 대량의 데 이 터 를 내 보 낼 때 예 를 들 어 Search / Scroll 로 매번 수만 개의 문 서 를 내 보 내 고 색인 내 보 낼 때
pprof
분석 을 통 해 반 직렬 화 는 대량의 CPU 순환 을 차지한다.따라서 특정 수 요 를 위해 극한 성능 을 추구 하기 위해 서 는 이에 대한 특별 처리 가 필요 하 다.
buger / jsonparser 사용 하기
다행히
olivere/elastic
는 PerformRequest
방법 을 제공 하여 누 드 바이트 로 돌아 갑 니 다. 우 리 는 기 존의 도구 구축 요 구 를 재 활용 한 다음 에 원래 바이트 로 돌아 가 스스로 처리 할 수 있 습 니 다.buger/jsonparser
라 이브 러 리 를 선택 하 였 습 니 다. 이 라 이브 러 리 는 원본 JSON 바이트 에서 특정한 내장 필드 를 검색 하고 배열 을 옮 겨 다 닐 수 있 습 니 다.반 직렬 화 된 구조 체 에 비해 필드 를 처리 하 는 방법 은 성능 을 크게 향상 시 키 고 메모 리 를 절약 할 수 있 습 니 다. 정확히 말 하면 추가 메모 리 를 소모 하지 않 습 니 다.경험 증, 반 직렬 화 에 사용 되 는 CPU 순환 은 기 존의 80% 에서 20% 로 줄 어 들 었 습 니 다.
buger/jsonparser
의 사용 방법 은 매우 간단 하 다. 공식 문 서 를 참고 할 수도 있 고 다음 과 같은 예 도 참고 할 수 있다.이 예 는 Elasticsearch 의 Search / Scroll 결과 에서
hits.hits
배열 의 _source
필드 를 가 져 오고 외부 리 셋 을 호출 하여 _source
필드 의 원본 JSON 바이트 를 전달 하 는 것 이다.// find hits.hits
var hitsBuf []byte
var hitsType jsonparser.ValueType
if hitsBuf, hitsType, _, err = jsonparser.Get(buf, "hits", "hits"); err != nil {
return
}
if hitsType != jsonparser.Array {
err = errors.New("hits.hits is not array")
return
}
// iterate hits.hits
var itErr error
var itCount int64
_, _ = jsonparser.ArrayEach(hitsBuf, func(value []byte, dataType jsonparser.ValueType, offset int, err error) {
itCount++
if itErr != nil {
return
}
srcBuf, srcType, _, srcErr := jsonparser.Get(value, "_source")
if srcErr != nil {
itErr = srcErr
return
}
if srcType != jsonparser.Object {
itErr = errors.New("missing _source in hits.hits")
return
}
if itErr = e.handler(srcBuf, e.count, e.total); err != nil {
return
}
atomic.AddInt64(&e.count, 1)
})
이 를 바탕 으로 포 장 된 라 이브 러 리 를 참고 하 세 요.https://github.com/guoyk93/esexporter
물론
[]byte
을 바탕 으로 검색 을 하 는 것 은 완전한 흐름 식 해석 이 아니 지만 반 직렬 화 된 다음 에 처리 하 는 것 보다 훨씬 좋다.기 존
*elastic.Client
대상 을 재 활용 하 는 것 을 고려 하지 않 는 다 면 다른 io.Reader
기반 JSON 스 트림 분석 라 이브 러 리 를 사용 하여 메모리 의 실시 간 추출 을 전혀 차지 하지 않 을 수 있 습 니 다.핵심 적 인 관점 은 특정한 수요 에 직면 하여 흐름 식 해석 은 성능 과 메모리 점용 을 크게 향상 시 킬 수 있다 는 것 이다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Golang 구현 대기열 및 스택대기열: 스택: github 주소:https://github.com/golibec/Lstruct.git 후속적으로 각종 데이터 구조와 주류 알고리즘을 지속적으로 보완할 것이다....
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.