-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
882c7d6
commit 3e7b5ec
Showing
12 changed files
with
956 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
snapshot을 복원하던 중 너무 많은 인덱스들을 하나의 머신에 복원했더니 계속해서 GC가 발생하는 문제가 생겼다. 이로 인해 CPU가 70% 아래로 떨어지지 않고 며칠이고 계속 유지 되었다. | ||
|
||
 | ||
|
||
현재 색인이 발생하거나 검색을 수행하는 작업을 하고 있지 않기 때문에 처음에는 왜 CPU 사용률이 떨어지질 않는지 이해가 되지 않았는데 메모리 부족으로 인해 GC가 발생하면서 CPU 자원을 많이 소모시켰기 때문에 발생한 문제였다. 이를 해결하기 위한 방법으로는 머신을 추가하여 노드를 더 구동시켜서 클러스터링 하면 되겠지만 근본적으로 메모리 소비량을 줄이고 싶었다. 특히나 우리 서비스는 검색이 많지 않고 색인에 대한 비율이 높기 때문에 검색 성능을 향상시키기 위한 쿼리 캐시나 샤드 캐시와 같은 기능을 사용하지 않아도 되었다. 그래서 먼저 캐시기능을 비활성화 시키는 것으로 메모리 사용량을 줄여보았다. | ||
|
||
|
||
|
||
아래 명령을 통해 캐시 사용량을 볼 수 있다. | ||
|
||
``` | ||
GET /_stats/request_cache?human | ||
GET /_nodes/stats/indices/request_cache?human | ||
``` | ||
|
||
|
||
|
||
필터 캐시를 비활성화 하기 위해서는 각 인덱스마다 인덱스 설정을 변경해야 하는데 현재 구동 중인 상태에서는 변경이 불가능했다. 이를 위해서는 아래와 같이 설정 전 후에 `_close`와 `_open`을 사용하여 인덱스 사용을 중단시키는 절차가 필요하다. | ||
|
||
```json | ||
POST /my_index/_close | ||
|
||
PUT /my_index | ||
{ | ||
"settings": { | ||
"index.requests.cache.enable": false | ||
} | ||
} | ||
|
||
POST /my_index/_open | ||
``` | ||
|
||
|
||
|
||
비활성화를 하게 되면 캐시 기능을 아예 사용하지 못하기 때문에, 약간의 캐시는 사용하고 싶다면 `config/elasticsearch.yml`파일을 수정하여 아래와 같이 캐시 사이즈를 조절할 수도 있다. | ||
|
||
``` | ||
indices.requests.cache.size: 2% | ||
``` | ||
|
||
|
||
|
||
## 참고 | ||
|
||
* https://blog.codecentric.de/en/2014/05/elasticsearch-indexing-performance-cheatsheet/ | ||
* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
## Kinesis | ||
|
||
* 키네시스 스트림 생성 | ||
|
||
``` | ||
aws kinesis create-stream \ | ||
--stream-name examplestream \ | ||
--shard-count 1 \ | ||
--region ap-northeast-2 \ | ||
--profile adminuser | ||
``` | ||
|
||
* 로그 정규표현식 | ||
|
||
``` | ||
(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2},\d{3}) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) (.*)$ | ||
``` | ||
|
||
* Kinesis 설정 | ||
|
||
``` | ||
{ | ||
"awsAccessKeyId": "", | ||
"awsSecretAccessKey": "", | ||
"cloudwatch.emitMetrics": true, | ||
"cloudwatch.endpoint": "monitoring.ap-northeast-2.amazonaws.com", | ||
"kinesis.endpoint": "kinesis.ap-northeast-2.amazonaws.com", | ||
"firehose.endpoint": "", | ||
"flows": [ | ||
{ | ||
"filePattern": "/usr/share/tomcat8/logs/*", | ||
"kinesisStream": "hive-dev", | ||
"partitionKeyOption": "RANDOM", | ||
"dataProcessingOptions": [ | ||
{ | ||
"optionName": "LOGTOJSON", | ||
"logFormat": "COMMONAPACHELOG", | ||
"matchPattern": "(\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2},\\d{3}) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) (.*)$", | ||
"customFieldNames": ["timestamp", "loglevel", "uid", "networktype", "packet", "data"] | ||
} | ||
] | ||
} | ||
] | ||
} | ||
``` | ||
|
||
* Lambda 생성 | ||
|
||
``` | ||
$ aws lambda create-function \ | ||
--region ap-northeast-2 \ | ||
--function-name ProcessKinesisRecords \ | ||
--zip-file fileb:///home/ec2-user/script/ProcessKinesisEvents.zip \ | ||
--role arn:aws:iam::xxx:role/LambdaKinessExecutionRole \ | ||
--handler example.ProcessKinesisRecords::recordHandler \ | ||
--runtime java8 \ | ||
--profile yongho | ||
``` | ||
|
||
* handler는 java인 경우 `example.ProcessKinesisRecords::recordHandler` | ||
|
||
* Lambda 연동 | ||
|
||
``` | ||
$ aws lambda create-event-source-mapping \ | ||
--region ap-northeast-2 \ | ||
--function-name ProcessKinesisRecords \ | ||
--event-source arn:aws:kinesis:ap-northeast-2:xxx:stream/hive-dev \ | ||
--batch-size 100 \ | ||
--starting-position TRIM_HORIZON \ | ||
--profile yongho | ||
``` | ||
|
||
* Lambda에 매핑된 이벤트 리스트 | ||
|
||
``` | ||
$ aws lambda list-event-source-mappings \ | ||
--region ap-northeast-2 \ | ||
--function-name ProcessKinesisRecords \ | ||
--event-source arn:aws:kinesis:ap-northeast-2:xxx:stream/hive-dev \ | ||
--profile yongho \ | ||
--debug | ||
``` | ||
|
||
* Lambda Test | ||
|
||
``` | ||
{ | ||
"Records": [ | ||
{ | ||
"kinesis": { | ||
"partitionKey": "partitionKey-3", | ||
"kinesisSchemaVersion": "1.0", | ||
"data": "SGVsbG8sIHRoaXMgaXMgYSB0ZXN0IDEyMy4=", | ||
"sequenceNumber": "49545115243490985018280067714973144582180062593244200961" | ||
}, | ||
"eventSource": "arn:aws:kinesis:ap-northeast-2:xxx:stream/hive-dev", | ||
"eventID": "shardId-000000000000:xxx", | ||
"invokeIdentityArn": "arn:aws:iam::xxx:role/LambdaKinessExecutionRole", | ||
"eventVersion": "1.0", | ||
"eventName": "aws:kinesis:record", | ||
"eventSourceARN": "arn:aws:kinesis:ap-northeast-2:xxx:stream/hive-dev", | ||
"awsRegion": "ap-northeast-2" | ||
} | ||
] | ||
} | ||
``` | ||
|
||
``` | ||
$ aws lambda invoke \ | ||
--invocation-type Event \ | ||
--function-name ProcessKinesisRecords \ | ||
--region ap-northeast-2 \ | ||
--payload file:///home/ec2-user/script/lambda-test.txt \ | ||
--profile yongho outputfile.txt | ||
``` | ||
|
||
* Lambda 함수 제거 | ||
|
||
``` | ||
aws lambda delete-function --function-name ProcessKinesisRecords --profile yongho | ||
``` | ||
|
||
|
||
|
||
## 참고 | ||
|
||
* [Kinesis로 App 로그 다루기](https://gist.github.com/haje01/5abaeadda792b40f39d7) |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
* elasticsearch는 2.x 버전 이전에는 Djb 해시 함수를 사용했었는데 이 후 부터는 murmur3 해시 함수를 사용함. | ||
|
||
* 아래 로직으로 샤드에 어떻게 분배되는지 확인해보니 거의 균일하게 배포됨 | ||
|
||
```java | ||
final int SHARD_SIZE = 5; | ||
int[] shards = new int[SHARD_SIZE]; | ||
for(int i = 0; i < 100000; i++) { | ||
int hash = Math.abs(Murmur3HashFunction.hash(String.valueOf(i))); | ||
int shardId = hash % SHARD_SIZE; | ||
shards[shardId]++; | ||
|
||
Thread.sleep(1); | ||
} | ||
|
||
for(int i = 0; i < SHARD_SIZE; i++) { | ||
System.out.println(String.format("shardId : %d, count : %d", i, shards[i])); | ||
} | ||
``` | ||
|
||
``` | ||
// 결과 | ||
shardId : 0, count : 19740 | ||
shardId : 1, count : 20016 | ||
shardId : 2, count : 19905 | ||
shardId : 3, count : 20032 | ||
shardId : 4, count : 20307 | ||
``` | ||
|
||
* 해시 말고 걍 랜덤으로 돌려도 거의 균일하게 배포됨 | ||
|
||
```java | ||
final int SHARD_SIZE = 5; | ||
int[] shards = new int[SHARD_SIZE]; | ||
Random rand = new Random(); | ||
for(int i = 0; i < 100000; i++) { | ||
int hash = rand.nextInt(2000000000); | ||
if(hash < 100000000) { | ||
hash += 100000000; | ||
} | ||
int shardId = hash % SHARD_SIZE; | ||
shards[shardId]++; | ||
} | ||
|
||
for(int i = 0; i < SHARD_SIZE; i++) { | ||
System.out.println(String.format("shardId : %d, count : %d", i, shards[i])); | ||
} | ||
``` | ||
|
||
``` | ||
// 결과 | ||
shardId : 0, count : 19959 | ||
shardId : 1, count : 20032 | ||
shardId : 2, count : 19926 | ||
shardId : 3, count : 20012 | ||
shardId : 4, count : 20071 | ||
``` | ||
|
||
* UUID를 사용해도 균일하게 배포됨 | ||
|
||
```java | ||
final int SHARD_SIZE = 5; | ||
int[] shards = new int[SHARD_SIZE]; | ||
for(int i = 0; i < 100000; i++) { | ||
UUID uuid = UUID.randomUUID(); | ||
int hash = Math.abs(Murmur3HashFunction.hash(uuid.toString())); | ||
int shardId = hash % SHARD_SIZE; | ||
shards[shardId]++; | ||
} | ||
|
||
for(int i = 0; i < SHARD_SIZE; i++) { | ||
System.out.println(String.format("shardId : %d, count : %d", i, shards[i])); | ||
} | ||
``` | ||
|
||
``` | ||
// 결과 | ||
shardId : 0, count : 20006 | ||
shardId : 1, count : 19830 | ||
shardId : 2, count : 20141 | ||
shardId : 3, count : 19863 | ||
shardId : 4, count : 20160 | ||
``` | ||
|
||
| ||
|
||
## 참고 | ||
|
||
* [elasticsearch Djb Hash함수](https://github.com/elastic/elasticsearch/blob/1.4/src/main/java/org/elasticsearch/cluster/routing/operation/hash/djb/DjbHashFunction.java) | ||
* [elasticsearch murmur3 Hash 함수](https://github.com/elastic/elasticsearch/blob/master/server/src/main/java/org/elasticsearch/cluster/routing/Murmur3HashFunction.java) | ||
* [Java HashMap은 어떻게 동작하는가?](http://d2.naver.com/helloworld/831311) |
Oops, something went wrong.