Elixir でサポートされる最大ランダム整数

2026/05/21 22:48

Elixir でサポートされる最大ランダム整数

RSS: https://news.ycombinator.com/rss

要約

Japanese Translation:

分散型 Elixir システムでは、ステートフルな

ExHashRing
と関数型の Rendezvous ハッシング (HRW) の間から選択することが一般的であり、それぞれ固有のトレードオフをもたらします。基本的な HRW 実装は線形時間計算量 O(n) に起因して劣化し、10,000 ノード環境では
ExHashRing
よりも 4,200 倍遅いものの、最適化された HRW バージョンは対数計算量を達成しており、ステートフルな
ExHashRing
が苦手とする高負荷環境で優れたキー分配を実現します。ベンチマーク結果では小規模構成(例えば 14 ノード)ではパフォーマンスの違いは軽微ですが、大規模スケールにおいては要件に応じて選択する必要があります:
ExHashRing
か、大量のノード数かつ高いスループットを必要とするケース向けの最適化された
HRW.Skeleton
、あるいは機能簡潔性とステートフルプロセス管理回避を重視する小規模システム向けに平仮名 HRW。エコシステムでは分配改善のための Murmur3 ハッシングなどの戦略もサポートされており、hex.pm 上のライブラリを活用して複雑なリング管理なしでこれらの選択を行える環境があります。

Improved Summary: 分散型 Elixir システムでは、ステートフルな

ExHashRing
と関数型の Rendezvous ハッシング (HRW) の間から選択することが一般的であり、それぞれ固有のトレードオフをもたらします。基本的な HRW 実装は線形時間計算量 O(n) に起因して劣化し、10,000 ノード環境では
ExHashRing
よりも 4,200 倍遅いものの、最適化された HRW バージョンは対数計算量を達成しており、ステートフルな
ExHashRing
が苦手とする高負荷環境で優れたキー分配を実現します。ベンチマーク結果では小規模構成(例えば 14 ノード)ではパフォーマンスの違いは軽微ですが、大規模スケールにおいては要件に応じて選択する必要があります:
ExHashRing
か、大量のノード数かつ高いスループットを必要とするケース向けの最適化された
HRW.Skeleton
、あるいは機能簡潔性とステートフルプロセス管理回避を重視する小規模システム向けに平仮名 HRW。エコシステムでは分配改善のための Murmur3 ハッシングなどの戦略もサポートされており、hex.pm 上のライブラリを活用して複雑なリング管理なしでこれらの選択を行える環境があります。

本文

集合ハッシュリング (Rendezvous Hashing):ステートレスで高機能な分散ハッシュリングの実装とベンチマーク

一貫ハッシュリング(Consistent Hashing)は、分散 Elixir システムにおいて分散レートリミッターキャッシュなどの重要な構成要素を実現する土台となります。

以前にこのテーマについて執筆しましたが、今回はより簡潔で汎用的な「集合ハッシュリング」のメリットと実装方法について解説します。


現状の課題:ExHashRing の弱点

分散システムにおいてノードへのキー割り当てを行う最も一般的なライブラリは、Discord が開発した

ExHashRing
です。これは長年の実戦で試練され、高い信頼性とパフォーマンスを誇ります。

しかし、いくつかの弱点があります:

  • プロセスの起動と管理が必要: リングのプロセスを開始し、**監督木(supervision tree)**の下に配置する必要があります。
  • 状態の保持: プロセスは永続的なオブジェクトとして状態を持ち続けており、その管理が常に必要となります。

著者は、このように「ステートフル」な代替案を求め、ステートレスな関数型アプローチに興味を惹かれました。


集合ハッシュリング (HRW) の概要

集合ハッシュリング(Rendezvous Hashing)は、ExHashRing よりもはるかにシンプルかつ汎用的です。ウィキペディアでは「最高ランダム重量(Highest Random Weight: HRW)」とも呼ばれます。

実装の簡易性比較

ExHashRing の例:

{:ok, ring} = ExHashRing.Ring.start_link()
Ring.add_nodes(ring, ["a", "b", "c"])

Ring.find_node(ring, "key1")
# => "b"

HRW の例(ステートレス):

HRW.owner("key1", ["a", "b", "c"])
# => "b"

HRW の主な特徴

  • 状態不要: プロセスの起動や初期設定が不要です。
  • 純粋な関数: 入出力に基づく関数プログラミングアプローチです。
  • クラスタ跨ぎの整合性: マシンを跨いで一貫性が保たれ、ノードリスト変更時にドリフト(偏移)が発生しません

パフォーマンスベンチマークと分析

1. ノード数が少ない場合(例:14 ノード)

ExHashRing は極めて高速ですが、HRW も実用的な速度でした。

項目ExHashRing.Ring.find_nodeHRW.owner
IPS2.67 M2.39 M
平均処理時間375.20 ns418.13 ns
中位値334 ns375 ns
  • 比較:
    HRW.owner
    ExHashRing の約 1.11 倍(+42.93 ns)遅いです。
  • 結論: ノード数が少ない場合のホットパスでは、この程度の差は無視できると判断されます。

2. ノード数が多い場合(例:10,000 ノード)

ノード数が指数関数的に増加すると、アルゴリズムの違いが顕著になります。

項目ExHashRing.Ring.find_nodeHRW.owner (O(n))
IPS1.91 M0.00046 M
平均処理時間0.00052 ms2.20 ms
  • 比較:
    HRW.owner
    ExHashRing の約 4,200 倍遅いです(+2.20 ms)。
  • 許容範囲: マシンでは約 2 ミリ秒かかりますが、用途によっては十分かもしれません。ただし、線形計算(O(n))のためノード増大に弱いです。

基本アルゴリズムの実装と改善

基礎的な HRW アルゴリズム

キーを各ノードに対してハッシュ計算し、最大値を持つノードを返すというシンプルなお作法です。

BEAM
:erlang.phash2
を使用します。

defmodule HRW do
  def owner(key, nodes) do
    Enum.max_by(nodes, fn node ->
      :erlang.phash2({key, node})
    end)
  end
end

HRW スケレトン(骨格)による最適化

ノード数が増える際の性能劣化を解消するため、ウィキペディアにあるクラスター分割技術を採用しました。

  1. ノードリストをソートしてクラスターに分割する。
  2. まずクラスターのアドレスを計算し、該当クラスター内のノードのみをハッシュする。

これにより、計算量は O(n) から O(log n) に改善されました。

スケレトンを使用したベンチマーク結果(10,000 ノード)

項目ExHashRing.Ring.find_nodeHRW.owner (skeleton)HRW.owner (O(n))
IPS2.17 M0.71 M0.00047 M
平均処理時間0.00046 ms0.00141 ms2.13 ms
  • 比較:
    • HRW.owner (skeleton)
      ExHashRing の約 3.06 倍遅い(+0.00095 ms)。
    • 改善効果: 処理時間を2 ミリ秒から 141 マイロ秒に大幅短縮しました。
  • 注意点: スケレトン構造体は追加/削除時にリストシフトが発生するため、厳密にはソート済みリストの扱いを考慮する必要がありますが、多くのユースケースで十分なトレードオフです。

ハッシュ関数の分布特性比較

ノード集合全体に対するワークロードの分散効率も検証しました。 キー数を 10 万、ノード数をそれぞれ 10, 100, 1000 と変化させた場合の標準偏差(stddev)を比较しました。

ベンチマーク結果のまとめ

ノード数:10 (理想的には各ノード 10,000 キー)

  • murmur3 x64_128
    : 最良(平均値の 0.98% の偏差)
  • murmur3 x86_32
    : 平均値の 1.12% の偏差
  • phash2 (HRW)
    : 平均値の 2.5% の偏差

ノード数:100 (理想的には各ノード 1,000 キー)

  • murmur3 x86_32
    /
    x64_128
    : 平均値の約 2.7〜2.9% の偏差(最良)
  • HRW.Skeleton
    : 平均値の 4.66% の偏差
  • ExHashRing
    : 劣悪(平均値の 27.97% の偏差、Min: 0 あり)

ノード数:1000 (理想的には各ノード 100 キー)

  • murmur3 x64_128
    /
    x86_32
    : 平均値の約 9.6〜9.8% の偏差(最良)
  • HRW.Skeleton
    /
    phash2
    : 平均値の約 9.8〜9.9% の偏差
  • ExHashRing
    : 劣悪(平均値の 31.42% の偏差、Min: 0 あり)

考察

  • :erlang.phash2
    は十分なパフォーマンスを発揮しており、特に小規模ノード数では最善の結果を出します。
  • MurMurMurmur3
    はノード数が少ない場合にわずかに優れていますが、本質的な違いではありません。
  • 最大の教訓: デフォルト設定の ExHashRing は、ノード数が増えるほど分布が偏りやすく(Min: 0 など)、大きなノード数で苦労することがわかりました。解決策は vnodes の増加ですが、今回は HRW がそれを回避できることを示しました。

結論と推奨事項

当プロジェクトでは、Hex.pm で公開した

hrw
ライブラリ(https://github.com/joladev/hrw)を完成させました。

シナリオ別への推奨

  1. 超大規模ノード数の場合:
    • ExHashRing
      または
      HRW.Skeleton
      を使用することを推奨します。
  2. 一般的なユースケースの場合:
    • ステートレスであり、設定が不要な単純な
      HRW.owner
      の使用を継続することを強く推奨します。

当ライブラリにはさらに拡張機能も含まれています:

  • HRW.Weighted
    : ノードに重み付けを付与し、特定ノードにキー空間を割り当てる(不均一なクラスタ向け)。
  • HRW.Bounded
    : キーの内容が事前にわかっている場合、分布の精度を高める機能。

どのようなご感想かお知らせください。

同じ日のほかのニュース

一覧に戻る →

2026/05/24 3:45

私の Writerdeck を語る時が来ました。

## 日本語翻訳: 著者は、6年経った System76 Galago Pro ラップトップを「writerdeck」と名づけたオフライン書写ステーションに変換し、X11、Wayland、およびデスクトップ環境を排する tty ベースの構成で Debian Trixie を実行することでミニマリズムを優先しています。コンテンツが公開共有を目的としているためフルディスク暗号化は省略され、管理には `sudo` ユーザーモデルに切り替えて root ログインが無効化されました。本質的なツールとして、Neovim がテキスト編集に使用され(従来のエディタに代わり)、Debian バックポートからの `kmscon` でスケーラブルなターミナルウィンドウを可能にし、セッション多重化には `tmux` を使用し、インストール済みの Network Manager 経由の `nm-tui` が Wi-Fi/WAN の管理に用いられます。電力モニタリングおよび画面明るさ制御は `acpi` と `light` コマンドで行われ、自動ログインと `.bashrc`内の起動スクリプトにより Neovim が `tmux` セッション内で動作し、ブート時に Vimwiki が起動するようにしています。Syncthing は Vimwiki フォルダをリモートサーバーに同期させ、ブラウザ GUI を必要とせずオフラインファーストなワークスペースを維持するために全てのネットワークアドレスを活用しています。この構成はデジタルの雑多さを削減し、悪い書写習慣を打破助けるとともに、クリエイティブ専門家にとってセキュリティと生産性を向上させます。

2026/05/24 7:25

自分でロールを作るな

## 日本語訳: 要約: 開発者は、暗号化やユーザーインターフェースコンポーネントといった重要な機能に対して独自の実装を即時に停止する必要があります。なぜなら、「自分自身でつくる」というソリューションは過去の実績が証明する通り危険であるためです。最も重要な教訓は、安全性と使い勝手を確保するために、自作コードの代わりに既成でピアレビューされた標準を採用しなければならないことです。独自のカスタム暗号化パッケージには、初期化の不備や予測可能なパターンなどの深刻な欠陥を内包しており、規制産業では財務規制に違反し、高額の罰則を引き起こす可能性があります。セキュリティの問題だけでなく、ネイティブブラウザ要素を置換することは性能低下をもたらし、過剰な JavaScript ロジックによりキーボードスクロールの破損やリンクの読み込み遅延といった問題を引き起こします。さらに、独自のソリューションは自動入力機能など、安全なパスワード管理などの重要なネイティブ機能を排除してしまいます。この傾向は、組み込みブラウザ機能の安定性よりも創造的なツールの構築を優先しており、ユーザー(高齢者のご家族も含まれます)が慣れ親しんだツールを常に再学習することを強いられています。これらの使い勝手に関する落とし穴を防ぎ、規制当局による罰金を避けるためには、開発者はネイティブ要素を置換するのではなく補完する方向へ転換すべきです。これにより、すべてのウェブサイトで一貫した動作を確保できます。

2026/05/21 6:21

私の二画面デスクセットアップ(2025)

## 日本語訳: 著者は、壁を向いた単調なパソコンデスクを部屋の方を向くように回転させることで(ドアを見渡させ、奥行きを追加)、そしてテック専用だった単一の面を、二つの明確なゾーニングに分かれた大規模な USM ハラーデスクに置き換えることにより、ハイブリッドなワークスペースへと成功裡に変化させています。このデザインは、ソーシャルメディアでのフィードバックを受けてから以前の壁を向いた配置が持っていた「古い」外観に対応し、また、未使用のアイテム、おもちゃ、プロジェクトをアナログ側の面に置き続けることで、ストイックなミニマリズムの限界を解決し、アイデアを刺激することを可能にしています。単純にチェアを二つの半分の間で移動させることで強化された明確な精神的境界線により、このセットアップは一つの表面上で「作業」「思考」「子供たちと過ごす時間」という 3 つの異なる機能を発揮します。9 ヶ月の使用後、著者は単一コンピューターの配置に戻る予定はないことを確認しており、むしろミニマリスト的な規律とマキシマリスト的な柔軟性を融合させたこの柔軟なシステムを維持する意欲を持っています。これにより、別々の部屋を必要とせずに、ワークフローと創造的アウトプットを向上させることができます。

Elixir でサポートされる最大ランダム整数 | そっか~ニュース