Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
A Redis compatible HLL implementation in Java
Search
Okada Haruki
August 02, 2019
Programming
360
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
A Redis compatible HLL implementation in Java
https://github.com/ocadaruma/pfutil
Okada Haruki
August 02, 2019
More Decks by Okada Haruki
See All by Okada Haruki
HyperLogLog feature of ClickHouse
ocadaruma
0
1.6k
HyperLogLog is interesting
ocadaruma
3
920
sbt-uglifier
ocadaruma
0
1.3k
Sparkが社内で流行ってきた話
ocadaruma
4
980
Other Decks in Programming
See All in Programming
Rでドレミ/Do-Re-Mi_with_R
florets1
0
130
SREの越境 / SRE Collaboration
y0hgi
2
310
Herb in Rails 8.2: Your ERB views, now HTML-aware @ Rails World 2026, Austin, Texas
marcoroth
0
220
Herb in Rails 8.2: Your ERB views, now HTML-aware @ Kaigi on Rails 2026, Tokyo, Japan
marcoroth
2
220
When benchmarks go bad - what I learned from measuring performance wrong
hollycummins
0
220
Kotlinの15年とServer-Side Kotlin
n_takehata
1
150
複雑なUIコンポーネントとの ⻑い付き合い⽅:波及するバグからテスト戦略を経て、安全な再設計へ
mixplace
0
410
見えないものを探る要求要件定義に必要な基本的思考 / invisible-requirement-thinking
minodriven
15
8.5k
JIS keyboard support in Omarchy
lef237
0
110
RAG の “R” を Swift で覗いてみる 〜「意味から探す」検索の仕組み〜
nao_randd
0
160
iOS 27でニュースアプリはどう変わる!? 〜日経電子版の新機能対応と、開発事例から〜
lynnswap
7
13k
Long Living Tokens, Die, Die, Die! (or: The One Ring is Banned in Modern)
sylph01
0
300
Featured
See All Featured
What the history of the web can teach us about the future of AI
inesmontani
PRO
2
740
ラッコキーワード サービス紹介資料
rakko
1
5.3M
StorybookのUI Testing Handbookを読んだ
zakiyama
31
7k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
47
8.4k
Avoiding the “Bad Training, Faster” Trap in the Age of AI
tmiket
0
270
Test your architecture with Archunit
thirion
2
2.4k
Primal Persuasion: How to Engage the Brain for Learning That Lasts
tmiket
0
500
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
52
6.1k
How to Align SEO within the Product Triangle To Get Buy-In & Support - #RIMC
aleyda
2
1.8k
The World Runs on Bad Software
bkeepers
PRO
72
12k
Discover your Explorer Soul
emna__ayadi
2
1.3k
How to make the Groovebox
asonas
2
2.5k
Transcript
Redis 互換なHyperLogLog の Java 実装を作った話 @ocadaruma
HyperLogLog ユニークカウントを高速・省メモリに推定する確 率的データ構造 Redis にも標準で入ってる
原理の直感的な説明 64bit int を一様ランダムに選んだとき、「左から 数えて1 が最初に立つのがk bit 目」である確率は 1/2^k
原理の直感的な説明 いいかえると、2^k 個ランダムに選ばないと「左端 の1 がk bit 目」であるような数が現れない つまりあるデータセットの要素を64bit hash にか
けて「左端の1 のbit 番号」だけ記録すれば、そのデ ータセットのユニークカウントを推定できる もちろんこれだけだと2^k 単位でしか近似できない し精度も悪いので、hash 関数をm 個使ってその平 均を取る、とか色々やる 実際は別々のhash 関数を用意するんじゃなくて もっと頭のいい方法でやる
HyperLogLog on Redis $ for i in `seq 1000`; rediscli
PFADD key $i > /dev/null $ rediscli PFCOUNT key (integer) 1001 $ for i in `seq 1000`; rediscli PFADD key $i > /dev/null $ rediscli PFCOUNT key (integer) 1001 $ for i in `seq 100`; rediscli PFADD foo a$i > /dev/null $ rediscli PFCOUNT foo (integer) 99 $ rediscli PFMERGE merged key foo OK $ rediscli PFCOUNT merged (integer) 1103
利用例 page やドメイン単位でUU 数をリアルタイムにレポ ートするシステム
PFMERGE は比較的遅い Redis 上で重い操作はあんまりしたくない
HyperLogLog の内部表現 普通に内部表現をGET できる 公式doc にもちゃんと書いてある https://redis.io/commands/pfcount rediscli> PFADD key
elem1 elem2 (integer) 1 rediscli> GET key "HYLL\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80i\xe1\x80N\ The HyperLogLog, being a Redis string,can be retrieved with GET and restored with SET. “ “
Java 側で操作できれば便利では? PFMERGE みたいな重い操作をRedis 上でやらず、 アプリケーション側に内部表現を持ってきて、 Java 上でやれると便利
pfutil https://github.com/ocadaruma/pfutil Redis v4 とv5 ではアルゴリズムがちょっと違う 内部表現は同じ どっちのアルゴリズムにも対応
例 $ amm > import $ivy.`com.mayreh:pfutil:0.1.1` > import com.mayreh.pfutil.v4.HllV4 >
val hll = HllV4.newBuilder().build() > (1 to 1000).foreach(i => hll.pfAdd(s"$i".getBytes)) > hll.pfCount() res4: Long = 1001L > val hll2 = HllV4.newBuilder().build() > (1 to 100).foreach(i => hll2.pfAdd(s"a$i".getBytes)) > hll2.pfCount() res7: Long = 99L > hll.pfMerge(hll2).pfcount() res8: Long = 1103L
まとめ 確率的データ構造面白くて便利!