Split View: HBase row key 디자인
HBase row key 디자인
Background
HBase의 row key 설계는 매우 중요하다. Row key의 범위로 region이 나뉘기 때문에 row key의 prefix가 잘 설계되지 않으면 hot spot region이 생겨 성능이 매우 떨어지게 된다. 이를 방지하기 위한 방법 중 하나로 row key 가장 앞쪽에 salt라는 것을 두어 row key가 다른 region들로 잘 분산되도록 저장하는 방법이 있다.
예시를 들면 만약 메시지를 저장할 때, <전송일>:<전송시간>:<message_id> 로 row key를 설계한다고 하면 아래와 같은 메시지는, 동일한 region server에서 처리될 것이고 성능 저하를 초래하게 됩니다.
230611:063031:1231231
230611:063032:1231232
230611:063032:1231233
230611:063033:1231234
230611:063033:1231235
만약 message_id를 앞쪽에 두면 어떨까?
1231231:230611:063031
1231232:230611:063032
1231233:230611:063032
1231234:230611:063033
1231235:230611:063033
이 또한 순차적으로 증가하는 message_id 때문에 write가 하나의 region으로 몰릴 것이다. 이를 방지할 수 있는 좋은 hash 값을 통해 salt를 row-key 앞에 prefix로 추가하는 것이다.
salt를 추가하면 row-key 구조는 <salt>:<전송일>:<전송시간>:<message_id>가 될 것이다.
salt는 다른 key를 hash함수에 넣어 return된 값을 사용하는데 그 이유는, hash 함수의 return 값의 길이가 일정하고 무작위성이라 region이 잘 분배되도록 하기 때문이다.
가장 많이 사용되는 SHA, AES, MD5 함수중 MD5를 사용해보겠다. salt로 MD5_function(message_id)를 넣어서 만들었고, 이때 row-key는 아래와 같습니다.
8D4646EB2D7067126EB08ADB0672F7BB:230611:063031:1231231
715782C59C0561E9B6CE0F3D522C32F1:230611:063032:1231232
57F962C03EF3526EC6E95CEB50785C4C:230611:063032:1231233
8B353D5CC07E13577608711F4602FCB7:230611:063033:1231234
430EDB0C535BF08174E122EFECFA711D:230611:063033:1231235
prefix 순서대로 되지 않기 때문에 달라졌기 때문에 region server 곳곳에 잘 흩어질 것을 예상할 수 있습니다. 이는 HBase의 Region server의 성능을 골고루 사용할 수 있어 성능향상에 큰 도움이 됩니다.
HBase Row Key Design
Background
The design of the HBase row key is very important. Since regions are divided by the range of row keys, if the row key prefix is not well designed, hot spot regions will occur, leading to significant performance degradation. One method to prevent this is to place a salt at the very beginning of the row key so that the rows are distributed well across different regions.
For example, if you design the row key as send date:send time:message_id when storing messages, the following messages would be processed by the same region server, causing performance degradation.
230611:063031:1231231
230611:063032:1231232
230611:063032:1231233
230611:063033:1231234
230611:063033:1231235
What if we put the message_id at the front?
1231231:230611:063031
1231232:230611:063032
1231233:230611:063032
1231234:230611:063033
1231235:230611:063033
This would also cause writes to concentrate on a single region due to the sequentially increasing message_id. A good way to prevent this is to add a salt as a prefix to the row key using a good hash value.
With salt added, the row key structure would become salt:send date:send time:message_id.
The salt uses the return value from putting another key into a hash function, because the hash function's return value has a consistent length and randomness, which helps distribute regions evenly.
Among the most commonly used hash functions -- SHA, AES, and MD5 -- let's use MD5. Using MD5_function(message_id) as the salt, the row keys would look like this:
8D4646EB2D7067126EB08ADB0672F7BB:230611:063031:1231231
715782C59C0561E9B6CE0F3D522C32F1:230611:063032:1231232
57F962C03EF3526EC6E95CEB50785C4C:230611:063032:1231233
8B353D5CC07E13577608711F4602FCB7:230611:063033:1231234
430EDB0C535BF08174E122EFECFA711D:230611:063033:1231235
Since the prefix order is no longer sequential, we can expect the data to be well scattered across different region servers. This allows for balanced use of HBase Region Server performance, greatly contributing to performance improvement.
Quiz
Q1: What is the main topic covered in "HBase Row Key Design"?
HBase Row Key Design
Q2: What are the key takeaways from this article?
HBase Row Key Design
Q3: How can the concepts in this article be applied in practice?
Consider the practical examples and patterns discussed throughout the post.