Rubyを使用したPostgreSQLパーティションテーブルの管理
巨大なテーブルから大量のデータを削除するとデータベースのパフォーマンスが低下する可能性があるため、プライマリPostgreSQLデータベースでパーティション化されたテーブルを使用して古いデータを効率的に期限切れにします。バージョン10より前は、PostgreSQLはパーティション化されたテーブルをネイティブでサポートしていなかったため、pg_partman拡張機能を使用してパーティション化を実装しました。これは、PostgreSQLのテーブル継承を使用して、パーティション化されるテーブルの子テーブルを作成し、親テーブルではなく子テーブルにデータを挿入するトリガーによって機能します。この拡張機能は私たちにとってはうまく機能しましたが、欠点があります。AmazonRDSを使用している場合は、サポートされていないため、オプションではありません。 PostgreSQLがネイティブパーティションをサポートするようになったので、その拡張機能を削除する時期が来たので、RDSを使用するオプションがあると思いました。
パーティショニングのユースケースは非常に単純です。時間に基づいてテーブルをパーティショニングし、すべてのパーティションに格納する行数と保持する期間に応じて、日、週、または月ごとに新しいパーティションを作成します。データ。すべてのパーティションテーブルにはcreated_at
があります 各行を格納するパーティションを決定するために使用される列。たとえば、次のように定義されたテーブルがあるとします。
create table events (
project_id integer,
data jsonb,
created_at timestamp
)
partition by range (created_at);
また、毎週パーティションを作成したい場合は、次のようになります。
create table events_p2019_10_28 partition of events for values from ('2019-10-28') to ('2019-11-04');
create table events_p2019_11_04 partition of events for values from ('2019-11-04') to ('2019-11-11');
時間ベースのパーティショニングスキームでは、古いデータの削除は、パーティションの1つを削除するのと同じくらい簡単です。次に、定期的なメンテナンスでは、日付範囲に近づくにつれて新しいパーティションを作成し、不要になったデータを含む古いパーティションを削除します。そのメンテナンスを少し簡単にするために、pg_partition_managergemを作成しました。当然のことながら、これはpg_partman拡張機能の使用経験に触発されており、非常に役立ちました。
上記のイベントテーブルとパーティショニングスキームを前提として、このgemをどのように使用するかを見てみましょう。次のようなスクリプトまたはrakeタスクを作成します。
require "pg_partition_manager"
PgPartitionManager::Time.process([{parent_table: "public.events", period: "week", premake: 1, retain: 3}])
parent_table
schema.table_name
として定義されています (public
、デフォルトのスキーマは、多くの場合、Rails開発者が最終的に使用する唯一のスキーマです)。 period
日、週、または月にすることができます。 premake
を使用して、事前に(現在の期間の後に)作成するテーブルの数を選択できます。 、およびretain
で(現在の期間の前に)保持するテーブルの数 。 premake
を指定しない場合、gemはデフォルトで4つのテーブルを事前に作成します 、およびretain
を指定しない場合、デフォルトで7日間、4週間、および6か月間データを保持します。 。
毎日のcronジョブでそのスクリプト/タスクを呼び出すと、すべての設定が完了します。必要に応じてテーブルが作成および削除されます。
すべてのActiveRecordクエリは、パーティション化されていないテーブルの場合と同じように機能するため、コードで変更する必要はありません。つまり、Event.create
、Event.where
、などはいつものように機能し、PostgreSQLはデータを挿入するときに適切なパーティションにデータを配置します。ただし、大量のデータがある場合に気付く可能性のある変更が1つあります... created_at
を含めると クエリでは、PostgreSQLはすべてのパーティションをスキャンする必要はありません。where句で指定した範囲をカバーするパーティションだけです。
要約すると、有効期限が切れたときに削除したい時間ベースのデータがたくさんある場合は、PostgreSQLパーティションテーブルとpg_partition_managergemを使用してアプリを満足させます。 :)
-
TCmallocを使用したRubyのメモリ割り当てのプロファイリング
Rubyではメモリ割り当てはどのように機能しますか? Rubyはページと呼ばれるチャンクでメモリを取得し、新しいオブジェクトはここに保存されます。 次に… これらのページがいっぱいになると、より多くのメモリが必要になります。 Rubyは、mallocを使用してオペレーティングシステムからより多くのメモリを要求します 機能。 このmalloc 関数はオペレーティングシステム自体の一部ですが、使用できる代替の実装があります。 それらの実装の1つは、Googleのtcmallocです。 TCmallocはGoogleパフォーマンスツールスイートの一部です。 これらのツールを使用し
-
Rubyでパーサーを構築する方法
構文解析は、一連の文字列を理解し、それらを理解できるものに変換する技術です。正規表現を使用することもできますが、必ずしもその仕事に適しているとは限りません。 たとえば、HTMLを正規表現で解析することはおそらく良い考えではないことは一般的な知識です。 Rubyには、この作業を実行できるnokogiriがありますが、独自のパーサーを作成することで多くのことを学ぶことができます。始めましょう! Rubyでの解析 パーサーの中核はStringScannerです クラス。 このクラスは、文字列のコピーと位置ポインタを保持します。ポインタを使用すると、特定のトークンを検索するために文字列をトラバ