Row Key Design for Tables in HBase

While developing schema for tables in Hbase, their were few questions which i came across & believe they seem very obvious that might be faced by any other programmer. So lets just Disscuss them briefly.

Ususally when we save data & keys are generally kept in auto-increment mode. Before i go further make sure we talking in context to datastore at a very high write speed. Continuing, so i’ll try to integrate many issues and solutions that i’ve come across through books, journals and blogs etc.

Schema design for Hbase is very different from schema design for Relational Database since relational databases have row based architectures whereas Hbase is specifically design in Columnar format. I’m just trying to set context before we dig deep.

Hbase Cluster serves multiple tables which are distinguished by name. Each name contains of rows. Each row contains cells which consists of row key + column family + column + timestamp against which Values are stored. Tables is split into Regions which contains table shards, each contains full rows defining start and end key which means rows of a table, lets say if it has 10k rows than they can distributed across multiple regions.

Each column family has got its own Hfile, this is the reason it is advised not to make too many Column-Families utill they are actually required.

Each region assigned to single Region Server & Regions are evenly distributed across Region servers.

Regions has configurable max size i.e. The amount of rows it can handle. When region reaches max size(or if pre-defined size), it is split into smaller region which can be assigned to other region servers.

regions_on_cluster

Logical View

physical_View

Physical View

HBase is a column-oriented database, no two rows in a table need have the same columns. To complicate matters further, data is versioned in HBase. The actual coordinates of a value (cell) is the tuple {row key, column key, timestamp}. In addition, columns can be grouped into column families, which give a database designer further control over access characteristics, as all columns within a column family will be stored in close proximity to one another.
A write operation in HBase first records the data to a commit log (a “write-ahead log”), then to an internal memory structure called a MemStore. When the MemStore fills, it is flushed to disk as an entity called an HFile. HFiles are stored as a sequence of data blocks, with an index appended to the file’s end. Another index, kept in memory, speeds searches for data in Hfiles.

HFiles are immutable once written. If a key is deleted, HBase records a special “tombstone” marker to commemorate the delete. Tombstones are removed (as is the deleted data) when HFiles are periodically compacted.
HBase attempts to satisfy read operations first through the MemStore. Failing that, HBase checks yet another in-memory structure, the BlockStore, which is a read cache designed to deliver frequently read data from memory, rather than from the disk-based HFiles.

HBase shards rows by regions, which are defined by a range of row keys. Every region in an HBase cluster is managed by a RegionServer process. Typically, there is a single RegionServer process per HBase node. As the amount of data grows, HBase splits regions and migrates the associated data to different nodes in the cluster for balancing purposes.
Rows are stored in ordered manner which should be taken into account since monotonically increasing values such as timestamp leads HOTSPOTTING.
Sharding : tables are distributed on the cluster via regions, and regions are automatically split and re-distributed as your data grows.

Lets discuss Hotspot first :-

Hotspotting occurs when a large amount of client traffic is directed at one node, or only a few nodes, of a cluster. This traffic may represent reads, writes, or other operations. The traffic overwhelms the single machine responsible for hosting that region, causing performance degradation and potentially leading to region unavailability. This can also have adverse effects on other regions hosted by the same region server as that host is unable to service the requested load.
As a remedy you can opt for :-
a) Salting
b) Hashing
c) reversing the key

Now Consider the case i want to discuss :

i’ve an HBase table where I’m writing the row keys like:
<prefix>~1

<prefix>~2

<prefix>~3

<prefix>~9

<prefix>~10
The scan on the HBase shell gives an output:
<prefix>~1<prefix>~10<prefix>~2<prefix>~3…<prefix>~9
How should a row key be designed so that the row with key <prefix>~10 comes last?

So he question arises

Rowkeys in HBase are kept sorted lexicographicallyirrespective of the insertion order. This means that they are sorted based on their string representations. Remember that rowkeys in HBase are treated as an array of bytes having a string representation. The lowest order rowkey appears first in a table. That’s why 10 appears before 2 and so on.

When you left pad the integers with zeros their natural ordering
for e.g.
000001
0000010
000002
.
.
.
000009
is kept intact while sorting lexicographically and that’s why you see the scan order same as the order in which you had inserted the data.

There are some general guidelines to be followed in order to devise a good design :

  • Keep the rowkey as small as possible.
  • Avoid using monotonically increasing rowkeys, such as timestamp etc. This is a poor shecma design and leads to RegionServer hotspotting. If you can’t avoid that use someway, like hashing or salting to avoid hotspotting.
  • Avoid using Strings as rowkeys if possible. String representation of a number takes more bytes as compared to its integer or long representation. For example : A long is 8 bytes. You can store an unsigned number up to 18,446,744,073,709,551,615 in those eight bytes. If you stored this number as a String — presuming a byte per character — you need nearly 3x the bytes.
  • Use some mechanism, like hashing, in order to get uniform distribution of rows in case your regions are not evenly loaded. You could also create pre-splitted tables to achieve this key cardinality in HBase
Advertisements

Currently Working as Game Developer at Gaussian Networks Private Limited , ( www.adda52.com ). Did B.Tech in computer science Engineering from G.G.S.I.P University , new delhi. Using Java , ActionScript 3.0 and PHP for development. I am a programmer who loves to adapt new platforms for coding. Reading techs & specs of gadgets is my hobby as i am a 24x7 active web crawler. I consider learning as a best helping aid to yourself as well as for others because it's the best means for diversifying your knowledge.

Tagged with: , , , ,
Posted in hadoop

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: