HBase MVCC and built-in Atomic Operations
By Lars Hofhansl (This is a follow to my ACID in HBase post from March this year) HBase has a few special atomic operations: checkAndPut, checkAndDelete - these simply check a value of a column as a precondition and then apply the Put or D
By Lars Hofhansl(This is a follow to my ACID in HBase post from March this year)
HBase has a few special atomic operations:
- checkAndPut, checkAndDelete - these simply check a value of a column as a precondition and then apply the Put or Delete if the check succeeded.
- Increment, Append - these allow an atomic add to a column value interpreted as an integer, or append to the end of a column, resp.
Increment and Append are not idempotent. They are the only non-repeatable operations in HBase. Increment and Append are also the only operations for which the snapshot isolation provided by HBase's MVCC model is not sufficient... More on that later.
In turns out that checkAndPut and checkAndDelete are not as atomic as expected (the issue was raised by Gregory and despite me not believing it first he is right - see HBASE-7051).
A look at the code makes this quite obvious:
Some of the Put optimizations (HBASE-4528) allow releasing the rowlock before the changes are sync'ed to the WAL. This also requires the lock to be released before the MVCC changes are committed so that changes are not visible to other transaction before they are guaranteed to be durable.
Another operation (such as checkAndXXX) that acquires the rowlock to make atomic changes may in fact not see current picture of things despite holding the rowlock as there could be still outstanding MVCC changes that only become visible after the row lock was release and re-acquired. So it might operate on stale data. Holding the rowlock is no longer good enough after HBASE-4528.
Increment and Append have the same issue.
The fix for this part is relatively simple: We need a "MVCC barrier" of sorts. Instead of completing a single MVCC transaction at the end of the update phase (which will wait for all prior transactions to finish), we just wait a little earlier instead for prior transactions to finish before we start the check or get phase of the atomic operation. This only reduces concurrency slightly, since before the end of the operation we have to await all prior transactions anyway. HBASE-7051 does exactly that for the checkAndXXX operations.
In addition - as mentioned above - Increment and Append have another issue, they need to be serializable transactions. Snapshot isolation is not good enough.
For example: If you start with 0 and issue an increment of 1 and another increment of 2 the outcome must always be 3. If both could start with the same start value (a snapshot) the outcome could 1 or 2 depending on which one finishes first.
Increment and Append currently skirt the issue with an ugly "hack": When they write their changes into the memstore they set the memstoreTS of all new KeyValues to 0! The effect is that they are made visible to other transactions immediately, violating HBase's MVCC. Again see ACID in HBase for an explanation of the memstoreTS.
This guarantees the correct outcome of concurrent Increment and Append operations, but the visibility to concurrent scanners is not what you expect. An Incremented and Appended value even for partial rows can be become visible to any scanner at any time even though the scanner should see an earlier snapshot of the data.
Increment and Append are also designed for very high throughput so they actually manipulate HBase's memstore to remove older versions of the columns just modified. Thus you lose the version history of the changes in exchange for avoiding a memstore exploding with version of the many Increments or Appends. This is called "upsert" in HBase. Upsert is nice in that it prevents the memstore being filled will a lot of old value if nobody cares for them. The downside is that is a special operation on the memstore, and hard to get right w.r.t. MVCC. It also does not work with mslab (see this Cloudera blog post for explanation of mslab).
If you don't care about visibility this is a simple problem, since you can just look through the memstore and remove old values. If you care about MVCC, though, you have to prove first that is safe to remove a KV.
I tried to fix this almost exactly a year ago (HBASE-4583), but after some discussions with my fellow committers we collectively gave up on that.
A few days ago I reopened HBASE-4583 and started with a radical patch that gets rid of all upsert-type logic (which set the memstoreTS to 0) and just awaits prior transactions before commencing the Increment/Append. Then I rely on my changes from HBASE-4241 to only flush the versions of columns needed when it is time to flush the memstore to disk. Turns out this is still quite a bit slower (10-15%), since it needs to flush the memstore frequently even thought it leads to mostly empty files. Still that was nice try, as it gets rid of a lot of special code and turns Increment and Append into normal HBase citizens.
A 2nd less radical version makes upsert MVCC aware.
That is actually not as easy as it looks. In order to remove a version of a column (a KeyValue) from the memstore you have to prove that is not and will not be seen by any concurrent or future scanner. That means we have to find the earliest readpoint of any scanner and ensure that there is at least one version of the KV older than that smallest readpoint; then we can safely remove any older versions of that KV from the memstore - because any scanner is guaranteed to see a newer version of the KV.
The "less radical" patch in does exactly that.
In the end the patch I ended up committed with HBASE-4583 does both:
If the column family that has the column to be incremented or appended to has VERSIONS set to 1, we perform an MVCC aware upsert added by the patch. If VERSIONS is > 1, we use the usual logic to add a KeyValue to the memstore. So now this behaves as expected in all cases. If multiple versions are requested they are retained and time range queries will work even with Increment and Append; and it also keeps the performance characteristics (mostly) when VERSIONS is set to 1.
原文地址:HBase MVCC and built-in Atomic Operations, 感谢原作者分享。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









MySQLMVCC の原理と実装の詳細な分析。MySQL は、現在最も人気のあるリレーショナル データベース管理システムの 1 つです。効率的な同時処理をサポートするためのマルチバージョン同時実行制御 (MultiversionConcurrencyControl、MVCC) メカニズムを提供します。 MVCC は、データベース内の同時トランザクションを処理する方法であり、高い同時実行性と分離性を提供します。この記事では、MySQLMVCC の原理と実装を詳細に分析し、コード例を示して説明します。 1.M

ビッグデータ時代の到来に伴い、データの処理と保存の重要性がますます高まっており、大量のデータをいかに効率的に管理、分析するかが企業にとっての課題となっています。 Apache Foundation の 2 つのプロジェクトである Hadoop と HBase は、ビッグ データのストレージと分析のためのソリューションを提供します。この記事では、ビッグデータのストレージとクエリのために Beego で Hadoop と HBase を使用する方法を紹介します。 1. Hadoop と HBase の概要 Hadoop は、オープンソースの分散ストレージおよびコンピューティング システムです。

MySQLMVCC の原則とベスト プラクティスの詳細な解釈 1. 概要 MySQL は、最も広く使用されているリレーショナル データベース管理システムの 1 つであり、同時アクセスの問題に対処するためのマルチバージョン同時実行制御 (MVCC) メカニズムをサポートしています。この記事では、MySQLMVCC の原理を詳しく説明し、いくつかのベスト プラクティスの例を示します。 2. MVCC の原則バージョン番号 MVCC は、追加の追加によるものです。

MySQLMVCC の原理を理解し、データベース トランザクション処理を最適化する 近年、データ量の継続的な増加とアプリケーション要件の向上に伴い、データベース トランザクション処理のパフォーマンスの最適化は、データベースの開発と運用保守において非常に重要なリンクとなっています。最も一般的に使用されているオープン ソース リレーショナル データベースの 1 つである MySQL の MVCC (Multi-VersionConcurrencyControl) 原理は、トランザクション処理において重要な役割を果たします。この記事では、MySQLMVCC の原則と

MySQLMVCC の原理をマスターしてデータ読み取り効率を向上させる はじめに: MySQL は一般的に使用されるリレーショナル データベース管理システムであり、MVCC (Multi-VersionConcurrencyControl) は MySQL で一般的に使用される同時実行制御メカニズムです。 MVCC 原則を習得すると、MySQL の内部動作原理をより深く理解し、データ読み取りの効率を向上させることができます。この記事では、MVCC の原理と、この原理を使用してデータの読み取り効率を向上させる方法を紹介します。

MySQLMVCC 原理分析: なぜそれが同時実行制御に最適な選択なのか?リレーショナル データベースでは、データの一貫性と同時実行性の制御が重要です。最も一般的なリレーショナル データベース管理システムの 1 つである MySQL は、MVCC (Multi-VersionConcurrencyControl、マルチバージョン同時実行制御) メカニズムを使用して同時実行制御を実現します。この記事では、MySQLMVCC の原理を深く分析し、それが同時実行制御に最適な選択肢である理由について説明します。 M

1. MVCCMVCC、正式名は Multi-VersionConcurrencyControl で、マルチバージョン同時実行制御です。 MVCC は同時実行制御方式であり、データベースへの同時アクセスを実現し、プログラミング言語でトランザクション メモリを実装するために、データベース管理システムで一般に使用されます。 MySQLInnoDB での MVCC の実装は、主にデータベースの同時実行パフォーマンスを向上させ、読み取りと書き込みの競合を処理するためのより良い方法を使用することを目的としています。これにより、読み取りと書き込みの競合が存在する場合でも、ロックや非ブロックの同時読み取りを実現できます。 2. 現在の読み取り値は、selectlockinsharemode (共有ロック)、selectforupdate、update、insert、de のようなものです。

SQLAND&OR 演算子AND 演算子と OR 演算子は、複数の条件に基づいてレコードをフィルタリングするために使用されます。 AND と OR は、WHERE サブステートメント内の 2 つ以上の条件を結合します。 AND 演算子は、最初と 2 番目の条件が両方とも true の場合にレコードを表示します。 OR 演算子は、最初の条件または 2 番目の条件のいずれかが true の場合にレコードを表示します。 「人物」テーブル: 姓名住所市区町村アダムスジョンオックスフォードストリートロンドンブッシュジョージ五番街ニューヨークカーター
