간략 설명
Geohash = Geohash에서는 위도와 경도를 가지고 Location마다 고유의 hash값이 붙게 되고 근접한 위치일수록 hash값의 접두사 부분이 비슷해진다. (https://en.wikipedia.org/wiki/Geohash )
Dynamodb-geo = DynamoDB에 Geohash 지리 데이터의 생성, 수정, 삭제, 근접 데이터 등의 함수를 지원해주는 package
(https://www.npmjs.com/package/dynamodb-geo)
DynamoDB와 hashKey와의 관계
Geohash는 위도와 경도를 가지고 Location마다 고유의 hash값이 붙게 되는데 hashKey가 partition key로 구성되어 길이에 따라 검색 성능이 좌우된다.
hashKey값이 길어질수록 partition이 분산시킬 수 있지만 반경에 커질수록 접근횟수가 더욱 많아진다.
hashKey값이 작아들수록 partition이 적어지지만 한꺼번에 많은 데이터를 읽어야 할 가능성도 커지므로 높은 RCU값을 요구할 수 있다.
글 목적
Dynamodb에 들어가는 데이터 구조에서 partition-key에 해당하는 hashKey의 최적의 길이 구하기
기본값은 6으로 설정되어 있는데 다른 길이를 사용할 경우 어떤 차이가 있을지 궁금해서 테스트를 해보았다.
테이블 구조
{
"Table": {
"AttributeDefinitions": [
{
"AttributeName": "hashKey",
"AttributeType": "N"
},
{
"AttributeName": "rangeKey",
"AttributeType": "S"
},
{
"AttributeName": "geohash",
"AttributeType": "N"
}
],
"TableName": "footprint-key10",
"KeySchema": [
{
"AttributeName": "hashKey",
"KeyType": "HASH"
},
{
"AttributeName": "rangeKey",
"KeyType": "RANGE"
}
],
"TableStatus": "ACTIVE",
"CreationDateTime": 1591854620.423,
"ProvisionedThroughput": {
"LastIncreaseDateTime": 0.0,
"LastDecreaseDateTime": 0.0,
"NumberOfDecreasesToday": 0,
"ReadCapacityUnits": 10,
"WriteCapacityUnits": 5
},
"TableSizeBytes": 84517270,
"ItemCount": 28921,
"TableArn": "arn:aws:dynamodb:ddblocal:000000000000:table/footprint-key10",
"LocalSecondaryIndexes": [
{
"IndexName": "geohash-index",
"KeySchema": [
{
"AttributeName": "hashKey",
"KeyType": "HASH"
},
{
"AttributeName": "geohash",
"KeyType": "RANGE"
}
],
"Projection": {
"ProjectionType": "ALL"
},
"IndexSizeBytes": 84517270,
"ItemCount": 28921,
"IndexArn": "arn:aws:dynamodb:ddblocal:000000000000:table/footprint-key10/index/geohash-index"
}
]
}
}
데이터 example
PMNTN_LT: { N: '0.29' },
PMNTN_GODN: { N: '4' },
rangeKey: { S: '113200102-13006' },
MNTN_CODE: { N: '113200102' },
hashKey: { N: '385416510' },
PMNTN_SN: { S: '13006' },
geoJson:
{ S:
'{"type":"POINT","coordinates":[127.02323388792045,37.66574049674894]}' },
PMNTN_UPPL: { N: '5' },
geohash: { N: '3854165107149761647' },
PMNTN_DFFL: { S: '쉬움' },
MNTN_NM: { S: '도봉산_자운봉' },
COORDINATES:
{ S:
'127.0220417676135,37.6649956621689,127.02236143526451,37.66508030050781,127.02290151424471,37.665459907141816,127.02323388792045,37.66574049674894,127.02350399697669,37.66613666211782,127.02375334541375,37.66654934059262,127.02412730644566,37.666961992186216' } }
테스트 nodejs source
const ddbGeo = require('dynamodb-geo');
const AWS = require('aws-sdk');
// Set up AWS
AWS.config.update({
accessKeyId: '-',
secretAccessKey: '-',
region: 'ap-northeast-2',
endpoint: new AWS.Endpoint('http://localhost:8000')
});
const ddb = new AWS.DynamoDB();
const config = new ddbGeo.GeoDataManagerConfiguration(ddb, 'footprint-key9');
config.hashKeyLength = 9;
const footprintManager = new ddbGeo.GeoDataManager(config);
console.time("check1");
footprintManager.queryRadius({
RadiusInMeter: 10000,
CenterPoint: {
latitude: 37.6584085,
longitude: 127.02928809999999
}
}).then(function(data){
console.log(data);
console.timeEnd("check1");
});
return;
아래는 각각 3만건 정도의 아이템이 들어있는 테이블을 hashKey 길이와 검색 반경을 다르게 해서 테스트 해본 결과이다.
반경 1km
차수|Key | 10 | 9 | 8 | 7 | 6 | 5 |
1차 | 10031.209ms | 721.379ms | 1006.917ms | 1370.448ms | 942.796ms | 922.263ms |
2차 | 3069.371ms | 975.226ms | 388.750ms | 436.482ms | 396.267ms | 601.796ms |
3차 | 2858.357ms | 944.124ms | 431.603ms | 410.343ms | 394.425ms | 385.747ms |
4차 | 3084.536ms | 1316.677ms | 392.813ms | 463.363ms | 382.464ms | 404.064ms |
5차 | 3364.704ms | 882.385ms | 403.927ms | 400.618ms | 403.406ms | 376.223ms |
평균 | 4481ms | 967ms | 524ms | 615ms | 437ms | 531ms |
반경 10km - key10은 error때문에 진행하지 않았다.
차수|Key | 10 | 9 | 8 | 7 | 6 | 5 |
1차 | - | 37188.304ms | 7158.762ms | 5251.057ms | 7551.026ms | 7401.075ms |
2차 | - | 33725.597ms | 5677.798ms | 3791.047ms | 4254.680ms | 3741.121ms |
3차 | - | 30395.661ms | 4929.117ms | 3829.746ms | 3752.136ms | 3782.613ms |
4차 | - | 27362.903ms | 4971.104ms | 3958.846ms | 3621.315ms | 3665.493ms |
5차 | - | 37190.278ms | 4939.326ms | 3792.199ms | 3632.907ms | 3712.111ms |
평균 | 33172ms | 5534ms | 4124ms | 4562ms | 4460ms |
반경 100km - key8 이상부터는 error때문에 진행하지 않았다.
차수|Key | 10 | 9 | 8 | 7 | 6 | 5 |
1차 | - | - | - | 25551.602ms | 16646.206ms | 15916.730ms |
2차 | - | - | - | 18529.825ms | 11139.500ms | 9787.848ms |
3차 | - | - | - | 17866.582ms | 16661.607ms | 10249.526ms |
4차 | - | - | - | 17827.254ms | 10570.851ms | 9639.297ms |
5차 | - | - | - | 23478.211ms | 9925.086ms | 9733.040ms |
평균 | - | - | - | 20650ms | 12988ms | 11064ms |
반경이 100km일때는 길이가 5인게 빠르지만 100km까지는 서비스하지 않을 예정이라 6으로 정했다.
'Web > AWS' 카테고리의 다른 글
[ AWS ] DynamoDB Local 환경 구축 오류 (0) | 2020.05.07 |
---|---|
[ AWS ] CloudWatch Alarm 설정하기 (0) | 2020.03.05 |
[ AWS ] System manager, CloudWatch를 통한 웹서버 로그 수집 설정 (0) | 2020.03.02 |
[ AWS ] 2019/10/15 Gameson AWS 행사 (0) | 2019.10.15 |
인스턴스 키(.pem) 분실시 교체요령 (0) | 2019.04.11 |
댓글