おはこんにちばんは! ユニファのインフラ見てますすずきです。
私は新年最初のブログになります。 そして春になれば私も入社4年が経つなと思い、ユニファのシステムの遍歴でもまとめてみるかとおもい、ブログに書いてみます。
ただ、入社前の部分も書いてるので、そのあたりが適当なのはご容赦ください。
続きを読むおはこんにちばんは! ユニファのインフラ見てますすずきです。
私は新年最初のブログになります。 そして春になれば私も入社4年が経つなと思い、ユニファのシステムの遍歴でもまとめてみるかとおもい、ブログに書いてみます。
ただ、入社前の部分も書いてるので、そのあたりが適当なのはご容赦ください。
続きを読むこんにちは、iOSエンジニアのしだです。
前回、Swift-Jupyter について書いたのですが、本当はSwift for TensorFlowを使って頭部姿勢推定(Head pose estimation)をやりたかったのでこちらをやってみたいと思います。
頭部姿勢推定は、カメラからみた頭の向きの推定を行うことです。 そのままですが、画像から頭の向きを pitch、 yaw、 roll の3つの値を予測することになります。
続きを読むあけましておめでとうございます!
エンジニアの田渕です。
みなさま、どんな年末年始を過ごされましたか?
ユニファは海外エンジニアも在籍しておりますので、きっと多種多様な過ごし方が……と思って話を聞いてみると意外と「寒いし混んでるんで出かけません。」と言う返事が多く(笑) 話を聞いてみると、国によっては日本みたいに「お正月だからホテルの料金が高くなる」みたいなことがないところもあるようなのです。 確かにそうなると、わざわざ高い時期に出かけることに躊躇いが出るのは納得です。
さて、まだ今年の仕事も始まって一週間経っておりませんが、早速年始からバタバタバタ……。。。 このブログも、うっかり書き忘れそうになっていたのを思い出し書いているところです。
昨年末のUniFa Advent Calendar 2019は好評のうちに終了。 (読んでくださったみなさま、ありがとうございました!執筆したみなさま、お疲れ様でした!) 最終日25日に書いたCTO赤沼の記事が良かったと内輪で話題になりましたので、 今回はその内容を受ける形で、私の方で今年の展望を書いて行こうと思います。
最近は色々な場所で、弊社のメンバーが登壇した際に「スマート保育園構想」と言う言葉を口にしていると思います。
改めて、「スマート保育園構想」とはなんなのか。
昨年3月の赤沼のインタビュー記事と、12/28(土)に放送されたBSフジの「この国の行く末2」のリンクです。
「この国の行く末2」
上の図は、前回のブログで書かせて頂いたRuby Biz Grandprix 2019のプレゼンテーション資料中の図です。 (この俯瞰図はうちのデザイナーが書いてくれたもので、とても好評です。)
当初は写真サービスである「ルクミーフォト」しかなかった弊社ですが、現在ではこの図に記載されていないサービスも含め、保育園・幼稚園・こども園内の業務のより広い範囲をカバー出来るようになっています。 直近では、「ルクミーシフト管理」のリリースも発表されました。
プロダクト/機能が増えていくこと自体は良いことですが、それに伴い新たに生まれてくる問題もあります。
作り手としては「システム構成・アーキテクチャの複雑化」、使い手としては「機能が多すぎて使いこなせない。」 特に後者の「機能が多すぎて使いこなせない。」と言う問題は、利用者の方々にご不便をおかけすることになるので、早急な対策が必要と考えています。
私はもともと地方出身なので、東京に来たばかりの頃は巨大なデパートの中で目的のものが探せずにとても疲れた思い出があります。自分が欲しいものだけが揃ったセレクトショップあったらなーとそんな時に思った訳ですが、弊社サービスをご利用頂く利用者の皆様にはそんなご苦労はおかけしたくない。。。
プロダクトに関しては、今年も昨年同様に新しい物をどんどん世に送り出しながら、プロダクトが増えた次の段階である
「より効率的に利用者の方がやりたいことをやれる様になるには。」
「欲しいものを、欲しいタイミングで見てもらえるには。」
を追求していくのが今年だと考えています。
さて、昨年は赤沼の記事中にもあった通り、エンジニアメンバーが大きく増えた年、多様化が進んだ年でした。 開発チームの19名の新メンバー中、11名は外国籍メンバー。 年末に行った忘年会では、各国の早口言葉で盛り上がったところもあったようです。
日本では当たり前の「お正月のATMのメンテナンス」。 毎年の恒例行事ながら、日本人でも忘れてしまう人がいます。 年末に外国籍メンバーから「他の外国籍メンバーに教えてあげたほうがいいです。」と言うお話を貰って慌ててアナウンスしました。 言われてみれば、日本での年末年始が初めての方は知らなくて当然です。
こんな感じで、日常的に「当たり前」と思っていることが実は当たり前じゃない、と言う経験をしています。 そのお陰で、最近では色々なことに対して「それって当たり前なんだっけ?」と考えられる様になってきた気がしています。
これは、プロダクトを作っていく中ではとても大切な感覚であり、今後役に立っていくといいなと思っています。
昨年は様々な方々を受け入れ、実際に業務をしていくための基盤づくりの年だったと思っています。
コミュニケーションはどうやって取るのが一番いいのか?
何が必要なのか?
色々と、みんなで試行錯誤してきました。 現在では各チームでそれぞれのやり方を見つけ、臨機応変に対応してくれています。
昨年は受け入れるところで精一杯でしたが、今年は「より効率的に、充実した情報を届けるには、質の高いコミュニケーションを取るには」と言う一歩先の観点を持ち、活動していきたいと思っています。
ここまで、「今年やっていきたいこと」について書かせて頂きました。
今年は、 「昨年広げた色々な物を整理/綺麗にしてより洗練させていく年」 と考えています。
また一年間、予想していることもしていないことも含め、色々なことがあると思いますが、来年は次のステージの抱負を書けるように、一年頑張っていこうと思います。
引き続き、変わり続けるユニファで一緒に保育をHackしてくれる方を募集中です!
今年も宜しくお願いいたします!
みなさまメリークリスマス、ユニファCTOの赤沼です。
UniFa Advent Calendar 2019 もついに最終日。この記事を読んでいただけているということは私もちゃんと役目を果たせたということで仕事納め気分です(まだ早い)。
さて、2019年ももうすぐ終わりですが、今年もユニファではスタートアップらしく、一年の間で色々なことがありました。その中で今回は開発に関連するトピックを雑に振り返った後で、最近思ったことを書いてみたいと思います。
プロダクトに関連することとしては、念願の一つであったルクミーフォトのリニューアルを実施しました。2013年創業時のファーストプロダクトであるルクミーフォトは、サービスの立ち上げスピードと初期ユーザ獲得を最優先としていました。リリースから時間も経ち、サービスのフェーズも変わってくるとどんなプロダクトでもレガシーな部分に対するコストが増大していきます。ルクミーフォトも今後のサービス拡大やユーザビリティ向上のためにも今リニューアルすべきという決断のもとリニューアルを実施しました。リニューアル中は大きな機能追加等はできなくなりますので、ビジネスのメンバーからも多大な協力を得て実現することができました。
また、今までリクルートマーケティングパートナーズさんが開発・運用されていた保育園向けICTサービスである Kidsly を、弊社の販売パートナーであるフレーベル館さんを経て事業譲渡いただき、弊社での開発・運用が開始しました。すでに多くのユーザに利用いただいている大規模なサービスの移管は弊社でも初めての経験で、手探りなことも多かったのですが、無事に完了し、今後のユニファの保育園向けICTサービスの中核となっていくプロダクトが加わりました。
ルクミー午睡チェックも正式リリースから一年が経過し、弊社初のIoTサービスとしてまずは1年間運用が行えたことにホッとしています。導入数も順調に伸びていますので、今後も安心・安全を提供するプロダクトとして安定的な開発・運用を続けていきたいと思います。
開発チームとしても体制が大きく変わりました。今年だけでも開発チームに19名の新メンバーが加入し、今までの倍の規模になりました。また、そのうち11名は外国籍メンバーということで、一気に多国籍チーム化が進みました。開発者採用はスタートアップにとっては特に厳しい市場環境である中、これだけのメンバーに入社いただけたのは本当に嬉しい限りです。
エンジニア以外にもディレクターやデザイナーメンバーも増え、各ロールでのチーム体制や、ディレクターを中心としたプロダクト開発体制も以前より充実させることができ、スクラムを主軸としたアジャイル開発プロセスのプラクティスも積極的に導入しています。ビジネスメンバーも含めたプラクティス浸透のための取り組みもメンバーが積極的に実施してくれているので、今後さらにプロセスの改善が進めていけるのではないかと思っています。
R&Dのメンバーも増員され、主に Machine Learning / Deep Learning 領域について今まで以上に幅広く取り組むことができてきました。ビジネスメンバーとも連携して、企画案についての技術的な実現可能性の検討なども行なっています。スタートアップでR&Dチームを置いているケースはあまりないと思いますが、我々が目指すスマート保育園の実現のためには欠かせないと思っています。
デザイナーも人数が増え、やっとチームと言える形になってきました。自社プロダクトのデザインはもちろん、外部向けの露出も増やしていくことができそうですし、社内全体においてのチーム作りという点でもデザインが持つ力は大きいと思っています。
ちなみに入社時から現在の規模になるまでのチームのスケールについては、今年の CTO Night & Day での登壇時にお話しさせていただき、下記の資料も公開しています。
今年多くの開発メンバーが入社してくれたということは、年始の段階でもそれだけの採用を見込んでたということで、今まで以上に外部向けの技術ブランディングに注力した年でした。以前から継続していた開発者ブログもメンバーが増えたことによって投稿数も大幅に増え、今回のような Advent Calendar が成立するまでになりました。昨年末からスタートした Podcast も不定期ながらなんとか継続し、今月で一年が経過しました。またカンファレンスのスポンサーも初めてやらせていただき、RubyKaigi や builderscon でスポンサーさせていただいた他、 RubyWorld Conference や ServerlessDays Tokyo、 プロダクトマネージャーカンファレンス等ではブースも出させていただきました。当日は登壇させていただく機会があったり、ブースにお越しいただいた方と色々とプロダクトについてお話しさせていただいたり、私たちとしても世界が広がっていく感覚を持つことができました。さらには自社単独や他社との共催での Meetup イベントも開始し、参加いただいた方の中から入社が決まった方もいました。
これらの実行については準備段階から実際の運用まで、今までの規模では行うことが難しかったですが、メンバーが増え、それぞれ積極的に協力してくれたからこそのもので、開発だけではなく人事や広報等の他の部署のメンバーの協力もあったからこそ実行できたものです。その甲斐あって最近他社の方と会って話をする際に、ユニファのことを目にしたことがある方が増えてきた感触がありますし、すでに繋がっていた方からも、露出機会の多さに注目いただくことが増えました。
また、今年はユニファ開発チームから初めて海外のTech系カンファレンスに1人ではありますが参加することができました。AWS re:Invent や Google I/O、 WWDC など、海外のカンファレンスは日本のものとはスケールが違いますし、最新の技術情報のキャッチアップももちろん重要ですが、何よりテクノロジーに対しての盛り上がりを実際に体験してくるということはとても重要なことだと考えています。来年以降どうなるかはまだわかりませんが、ひとまず最初の一歩が踏み出せたという点では前進できたと思っています。
ここまでは主に今年やったこと、規模が大きくなったことでできるようになったことをお話ししてきましたが、一方で、できないことも増えてきているとも感じています。規模が小さい時には、今後人数が増えてくればどんどんできることも増えていって、できないことは減ってくるイメージをしていましたが、実際に開発チームや会社全体の規模が大きくなってくると、もちろんできることが増えてきてはいるものの、今までとは違ったできないことが増えていっているという感じです。
プロダクト数や開発チーム、会社規模が拡大してくると、工数などの問題以外にも様々な力学が発生してきます。また、人が増えればやりたいことの総数も増え、指向性も多様になっていき、いずれかを選択せざるを得ないケースも増えてきます。さらにスタートアップとしては対象とする業界の情勢や自社の状況などは日々めまぐるしく変わっていきます。
こういった中では、会社も個人も自分を変えていき、向上させていく必要があります。自分が今までと同じアウトプットを出していたとしても、周りが変わっていき向上していく中では、相対的に自分達のバリューは下がっていってしまいます。
一方で、どれだけ変化する状況の中でも変えてはいけないもの、守らなくてはいけない大事なものがあるのも確かだと思っています。この、変えていくべきことと変えてはいけないことの判断は簡単ではありません。痛みを伴ってでも変えるべきことなのか、流されずに抗うべきことなのか、この判断がとても難しいと最近は感じています。経営、チーム、プロダクト、どの面を取ってもこの判断を間違えた場合、リカバリが困難になる可能性があります。
日々の 1 on 1 等でメンバーと話す中で上がってくるボトムアップでの課題、マネージャー陣から上がってくる会社組織としての改善点、経営陣と話す中で論点になる事業上の問題点など、それぞれ違った視点から、みんなもっと現状を改善したいという想いで様々な課題があげられます。意思決定をしていく立場としては、上がってきている課題は適切な内容か、自分の判断は会社の経営者として正しいのか、CTOとして開発視点から通すべきことを主張できているか、単にメンバーの要望に迎合しているだけになっていないか、他の経営陣の声に流されていないか、セクショナリズムを排除してフラットに判断できているか、こういった様々な思いが日々渦巻いています。
自分の判断が正しかったのかどうかはその瞬間にはわかりません。後になってわかるものです。そうした中で意思決定していく上で大切なのは、自分の中で芯のある結論を出せたか、これで間違っていたら仕方ないと思えるような、これならメンバーにどう思われても仕方ないと思えるような決断になっているかなのかなと思っています。なんとなくで決めてしまったものは失敗することも多いですし、その後もモヤモヤしたものが残りがちです。もちろん考え抜いた上で決定したことでも失敗することはあるのですが、その場合には自分の中で整理もつけやすく、次に向けてピボットしていける気がしています。要はそれぞれの意思決定に対して自分にも他者にも真摯に向き合って手を抜かずに考え抜けたかどうかなのだと思っています(できているとは言ってない)。
さて、とりとめもなく色々と書いてしまいましたが、我々ユニファ開発チームは来年も保育をハックしていきます。この「保育をハックする」というのは我ながら開発チームのマインドを一言で表していて良い感じだなぁと思っています。また、上記で色々と書いたように組織としてももっと強くしていく必要がありますので、チームをハックしていくことも必要だなと思っています。今年は技術ブランディング等で外向けの施策にも注力していましたが、来年はどちらかというとチームを強くしていくための内部的な施策に重点を置きたいなと思っていますので、保育をハックしていくためのより強いチームを作っていけたらと思っています。一緒に保育をハックしていくためにチームに加わっていただける方もまだ募集していますので、興味のある方はぜひご連絡ください。
今年の Advent Calendar の記事としてはこれが最終回となりますが、今後もいろんなところで露出していけるように頑張りたいと思います。また、一年後に2020年を振り返った時に、あの決定は正しかったと言える決定を一つでも増やせるように取り組んでいきたいと思いますので、このブログを始め、引き続きユニファをよろしくお願いします。それでは、良いお年を。
~お品書き~
あらこんばんは、私「スナック洋子」というスナックのママをやらせていただいております洋子と申します。
昼間は ディレクター 兼 QA をやっておりまして、二足の草鞋を履かせていただいております。
あ、 ディレクター 兼 QA 兼 ママ なので三足ですわねおほほ。(足は三本もない。)
すみませんちょっとつらくなってきたので、ここからはいつもの感じで書きますね。
今回は社内コミュニケーションを活性化させる場としてこういう方法もあるよーってことで紹介できたらいいなーと思っております。
ゆるい話なのに、思ったより長くなりましたすみません。
8月にオープンしたばかりでして、ママとしてはまだまだ駆け出しです。
「スナック洋子」は社内向けと社外向け、それぞれで開店しています。
今回は「社内向け」のお話がメインです。
(社外向けは最後にチラっとだけ話します。)
社内では月に一度、最終金曜日に開催しています。
開催場所はオフィスの一角でやっています。
会社もなかなか大変なフェーズなので、社内はドタバタ。もう本当にドタバタ。
そんな中、みんなにとって「気晴らしの場」でも「ただ楽しい場」でもなんでも良いのでつくりたかったという感じです。
「あー疲れたなーちょっとスナック寄って帰るかー」
「お、なんかやってる楽しそうー」
ってみんなに思ってもらえていたら大成功です。
ユニファはものすごい勢いで社員が増えています。
(私が入社した4年前は15人で、今や150人以上…!10倍やばい…!)
会社の規模がおおきくなってくると一度も話したことがない!という人が出てきます。
私の体感ですが、100人を超えたくらいから発生しはじめる気がします。
部署をまたいでのコミュニケーションが減り「あそこの部署何やってんだ状態」や、「もはや正社員かパートさんか委託さんなのかがわからない状態」や「役員と一度も直接しゃべったことない状態」ですね。
それを少しでも減らすために、会話をするきっかけをつくれたらなーと思っています。
「最近何してんのー?」
「お、はじめましてー!」
「土岐でございます」←CEO
って会話が生まれていたら大成功です。
今までの話全部忘れてもらっていいくらいここです!(笑)
ママが一番楽しまなくてどうするんですかくらいに思っています。
何事も続けるには運営している側が楽しまなきゃ続かないですよ。(仕事も同じだと思う。)
私は会社のみんなが好きなので、みんなが楽しそうにキャッキャウフフしているのを見ながらお酒が飲めればそれが私にとっての最高です。
といっても、自分でつくってないんですよねこれが(笑)
私個人的な話をしますと、私は「人と酒が好き」って理由でスナックをやるのが夢だ!ってみんなに宣言していました。
そんな中、オフィス移転をしまして、カウンターが設置されました。
これはスナックいけるのでは…!って思っていたところ、
みんながロゴをつくり、名刺をつくり、看板をつくり、勝手にスナックが出来上がりました(笑)
打ち合わせして戻ってきたらスナック洋子しあがっててウケたし、Slackの絵文字もできててさらにウケてた
— tsuruoka@カシャプシュ (@tsuru_beer) 2019年7月31日
#オフィス移転3日目 pic.twitter.com/GUlOwlyiOU
昼休みになんかごそごそやってるやつらいるなーと思って打ち合わせして戻ったら看板できてた人生#100均でよくここまで作ったなwwwww pic.twitter.com/2P3kGnz73w
— tsuruoka@カシャプシュ (@tsuru_beer) 2019年8月2日
さて、スナック自体はみんなの力でできました。
次は運用ルールや集客です。
叩きはスナック洋子の後援者の方が作成してくれました。(みんなで作っている感じ良いね。)
叩きを元にこんなのもあったほうがいいよねーって話をして決まった内容が以下です。
趣旨と目的
ルール
これができたら役員や部長陣へ「本当にスナックやるよー!」って宣言と総務の了承を得てきます。
ありがたいことに、会社としてGOGOでした。
こういう活動の背中を押してくれる会社は良いなーと思いました。(いつか予算もぎとりたいと思っている。)
Slackにチャンネルを作成して、お客さまへの連絡や活動報告をする場としました。
開催後にはこんな感じで報告しています。
お客さまのお金を預かる以上、ちゃんと報告はしないとですよね。
全社員がいるSlackチャンネルで活動開始のご連絡をし、チャンネルへ入ってもらいました。
2回目以降も同じ感じで、全社員へ周知→チャンネル誘導→チャンネルで詳細をご連絡、という形です。
開店までにやったことを箇条書きします。
そりゃあもうみんなの笑顔ですよね!(なんつって)
仕事やプライベートな話から、ボードゲームやったり、そりゃもうキャッキャウフフですよ。
実際みんなの話を聞いていると、狙った部分の会話もしてくれていたりと、最高でした。
また、役員もよく遊びに来てくれるのでみんな役員とたくさん話せて楽しそうでした。
実際の効果がどれくらいあったのかはどうやって測ろうかなぁは考えていますが、
それよりもみんなが楽しんでくれていればもう大成功なのではって正直思っています。
もちろん課題もあるのでそれは今後運営しながらカイゼンしていき、より良いスナックにしていきたいと思っていきます。
CEOに大きい冷蔵庫をねだろうかと思っています。
(土岐さーーーん見てますか!?冷蔵庫欲しい!冷蔵庫冷蔵庫!!!)
社内でスナックをオープンさせると楽しいよ!
場をつくるのはちょっとたいへんだけど、それ以上に測れない何かを得られるよ!
ということで以上です。
思っていたより長くなりました、最後まで読んでくれたあなたはもうスナック洋子のお客さまです!
ちなみに社外向けの「スナック洋子」については、採用活動の一環としてオープンしております。
などなど、ユニファに興味があるかたはどうぞご来店ください。
(TwitterとかFacebookとか、なんとかしてママに連絡とってもらえれば日程調整して開催します!)
看板設置するだけでどこでも「スナック洋子」になるので簡単なのです(笑)
それではみなさまのご来店を心よりお待ちしております。ママより
うちのおじさんから名刺作ったよ?と連絡きて社内大爆笑だった
— tsuruoka@カシャプシュ (@tsuru_beer) 2019年8月1日
#みんな仕事はやすぎ pic.twitter.com/CFlM3bw2JG
こんにちは、プロダクト開発部のちょうです。最近だいぶ寒くなってきて、こたつからなかなか出られません。こたつとみかんがあれば一日いきれると思いつつ、普段自分が学んでいる内容をすこし紹介したいと思います。
今回の内容はBloom Filterです。Bloom Filterは一言でいうと、空間効率のいい確率的データ構造です。要素が集合のメンバーであるかどうかのテストに使われます(wikipediaより)。確率ですので、使えるものではないと思う人が多いかもしれないが、Bloom Filterの特徴を理解すれば問題なく利用できます。
要素が集合のメンバーであるかどうかを確認するには、一番普通の方法はHash関数を元にするHashSetというデータ構造を使います。HashSetは基本 O(1) の速さで判断できます。もちろん、Hash関数による衝突の可能性があります。最悪の場合、HashSetの内部tableのサイズを倍にする必要があります。それに、要素数が非常に多い領域では、普通のHashSetだと空間効率が悪いと予想できます。ここで、Bloom Filterの登場です。
Bloom Filterは空間効率のいいデータ構造です。なぜなら、利用するメモリー領域を倍にする必要がありません。最初から固定してもいいです。それと、Bloom Filterの要素の単位は bit です。32bitマシンでinteger型だと最大32個の要素が入れます。
Bloom Filterは複数のHash関数を利用します。一つのHash関数だと衝突による実際集合のメンバーではないのにメンバーですという結果になる可能性が高いので、複数Hash関数で可能性を減らします。
サイズは8のBloom Filterを例にします。
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
最初すべてのbitが0です。要素 foo
を入れます。Hash関数を3つにしましょう。Hash1、Hash2とHash3。3つのHash関数の結果は2, 4と7とします。
| 0 | 0 | 1 | 0 | 1 | 0 | 0 | 1 |
foo
を入れたBloom Filterです。indexが2、4と7の位置を1にセットします。次は要素 bar
を入れます。3つのHash関数の結果は1, 2と3とします。
| 0 | 1 | 1 | 1 | 1 | 0 | 0 | 1 |
同じく、indexが1、2と3の位置にセットします。
では要素をテストしましょう。要素 foo
でテストすると、3つのHash関数の結果で、場所2、4と7にすべて1にセットされ、メンバーであるということになります。同じく要素 bar
でテストしてもメンバーであることもわかります。
続いてメンバーではない要素をテストします。 要素 aaa
にたいして、Hash関数の結果を2, 5, 7とします。index 2と7に1がセットされましたが、5がセットされないです。ゆえ、 aaa
がメンバーではありません。要素 bbb
にたいして、Hash関数の結果は2、3と4とします。すべての位置に1がセットされ、メンバーであるという結果になりますが、実際はメンバーではありません!
ここでわかったことは、Bloom Filterはメンバーではない要素でもメンバーであるという結果になる可能性があります。これはfalse positiveということです。こういう問題があって、Bloom Filterは使えものにならないと思う人がいるかもしれないが、Bloom Filterはメンバーではない要素をメンバーであるという結果にならない(つまり、メンバーではない結果でしたら絶対メンバーではない)です。まとめてみると、
要素 | 事実 | テスト |
---|---|---|
foo | メンバー | メンバー |
bar | メンバー | メンバー |
aaa | メンバーではない | メンバーではない |
bbb | メンバーではない | メンバー |
要素 aaa
はメンバーではないの結果なので、メンバーではないということが断言できます。逆に、メンバーであるという結果になったら、メンバーではない可能性があります。
こういう特徴を受け、Bloom Filter + DBの使い例を考えみましょう。
DBに100万のレコードがあり、サイズ200万(メモリーやく244KB)のBloom FilterをDBの前にします。毎回レコードを取得するとき、まずBloom Filterを通して、もし存在しないなら、レコードはかならず存在しないので、存在するレコードだけDBと問い合わせします。
こうすることで、Bloom Filterでいらない問い合わせを減らすことができます。Bloom Filterの確率的という特徴もカバーできます。実際、Bloom Filterを利用するシーンはほとんど、レコードは非常に多く、例えばメールボックスのSpam Filter、Bloom Filterなしだと裏側のデータソースへものすごく負荷をかかることが予想できます。
Bloom Filterの特徴を理解できると、以下のような簡単なBloom Filterが書けます。
import java.util.* interface Hasher<K> { fun apply(key: K): Int } class SimpleStringHasher( private val seed: Int, private val max: Int ) : Hasher<String> { override fun apply(key: String): Int { return key.fold(seed) { acc, c -> acc * seed + c.toInt() } and (max - 1) } } class SimpleBloomFilter<K>( private val bitSet: BitSet, private val hashers: Collection<Hasher<K>> ) { fun mightContains(key: K): Boolean { return hashers.all { bitSet.get(it.apply(key)) } } fun put(key: K) { hashers.forEach { bitSet.set(it.apply(key)) } } } fun main() { val size = 2048 val bloomFilter = SimpleBloomFilter(BitSet(size), listOf( SimpleStringHasher(1, size), SimpleStringHasher(7, size), SimpleStringHasher(23, size) )) for (i in 1..1000) { bloomFilter.put(i.toString()) } println((1..2000).count { bloomFilter.mightContains(it.toString()) }) // 1024 -> 1582 // 2048 -> 1000 }
SimpleBloomFilterのソースコードをすこしみてみましょう。mightContainsはすべてのHash関数が計算した位置に1がセットされればtrueを返します。putはすべてのHash関数が計算した位置に1をセットします。
main関数では、サイズ2048のBloom Filterを作ってました。それと1から1000までという要素をBloom Filterに入れます。最後は1から2000までの要素でテストします。サイズは2048だと、最後はきれいに1000とカウントされますが、サイズ1024の場合は1582の結果になります。ぜひ試してください。
最後に、false positiveつまり誤判断を減らすにはサイズどれぐらいにすればいいでしょうか。その質問にたいして、Bloom Filterの論文に答えがありますが、ここで結論を出します。
Pfpをfalse positiveの確率とします。nは入れようとする要素の数です。mはBloom Filterのサイズです。
m = - (n * ln Pfp) / (ln 2) ^ 2
おまけに、Hash関数の数kも
k = (m / n) * ln 2
いかがでしょうか。すこしBloom Filterに理解していましたでしょうか。普段の開発に使わないかもしれないが、こういうものがあると覚えていただければ幸いです。
「国外IPアドレスフィルタ」をOFFにしましょう。
みなさんこんにちは。
ユニファ初のアドベントカレンダーの12月22日を担当します。サーバーサイドエンジニアの柿本です。
知り合いに頼まれてホームページを作ることがあります。まあ本職ではないしデザインセンスの問題もあるのですが、それほどのレベルは求められないのでお小遣い稼ぎと思って作ります。
*ちなみにユニファは副業OKです!ユニファの数ある良いところのうちの一つですね。
静的サイトを作る時もソースコードをGitHubで管理しますが、ホスティングサーバーにFTPでアップして、それとは別にGitHubにpushするという二度手間をなんとかしたいと思っておりました。
GitHub Pagesを使えばpushするだけで反映されますが、サーバーサイドスクリプトが使えません。つまり、問い合わせフォームを置くのが難しくなります。
GitHub ActionsはGitHubのリポジトリにビルトインされているのでお手軽に使えるし、レンタルサーバーにFTPすればPHPも使えます。
GitHub Universe 2019で正式版リリースが発表されたばかりですね。早速使ってみます。
GitHub Actionsでやりたいことはたった一つ
masterブランチにpushされたら「さくらのレンタルサーバ」にFTPする
GitHub Actionsのセットアップの仕方をここにつらつらと書こうと思ったのですが、ネットで検索すればたくさん情報が出てくるので割愛します。
最終的な私の成果物はこちら↓↓↓
GitHub Actionsがいかに簡単に使えるかはご理解いただけると思います。
FTP-Deploy-Action
というFTP関係のものでは比較的人気のあるサードパーティ製のactoinsを使って実行したのですが、待てども待てども終わりません。
lftpを直に使ってもダメでした。
curlでftpを使ってもダメでした。
SFTPにしてみても、ダメでした。
その他100通りくらい(は大袈裟ですが 汗)の手段を試しましたが、どれもダメでした!!
自分のmacでubuntu:latestをdockerで走らせて、そこからは問題なくFTPできるのですが、なぜかGitHub Actionsでは動きません。
気づいてしまえば、「まあそうだよね」て話なのですが、FTPサーバーのIP制限が原因でした。 さくらのレンタルサーバはデフォルトで「国外IPアドレスフィルタ」がONになっています。 help.sakura.ad.jp
GitHubのサーバーが海外であることは想像に難くないですね。このフィルタ機能をOFFにしましょう。
1晩頑張ってうまくいかなかったらテクニカルサポートに問い合せしよう。
おそらく一瞬で解決したと思います。
3日3晩寝不足になっても技術が好きな人を募集中です。(寝るのも大事)