Hele maika'i

趣味とか技術とかざっくばらんに書いてます。タイトルはハワイの言葉で「幸せな一歩」

メールなど採用歴

ずっと使っていたツイフィールがついに文字数制限に引っかかって更新できなくなったので、 今後はメール採用歴をこちらに残していくこととする

2015

2016

2017

ゆいかおりの実♪(ふつおた) 6/5

2018

2019

2020

2021

2022

2023

2024

参加イベント一覧


ずっと使っていたツイフィールがついに文字数制限に引っかかって更新できなくなったので、 今後は参加イベントをこちらに残していくこととする

記載基準はお金を払っていることです。

ライブチケットを買う。CDを買って応募したリリースイベント、オンラインで視聴チケットを買って参加したもの。

何かしらちゃんとお金を払ったものについて記載しており、無料で見れるオンラインイベントなどは記載していません。

2014

2015

2016

2017

2018

2019

  • LAWSON presents Sphere 10th anniversary Live "Ignition"
  • 石原夏織のCarry up&up!? in サイエンスホール 両部
  • THE IDOLM@STER MILLION LIVE! 6thLIVE TOUR UNI-ON@IR!!!! 仙台Angel STATION 両日 LV
  • 肉フェス
  • 水樹奈々 幕張イベントホール座長公演“水樹奈々大いに唄う 伍"
  • THE IDOLM@STER SideM 4th STAGE ~TRE@SURE GATE~ 両日 LV
  • THE IDOLM@STER MILLION LIVE! 6thLIVE TOUR UNI-ON@IR!!!! 神戸Princess STATION 1日目 LV,福岡Fairy STATION 2日目 LV,SPECIAL 両日
  • 石原夏織トークショー<芝浦工業大学 大宮祭>
  • 石原夏織 Sunny Spot Story リリースイベント 「CARRY PLAYING+ きゃりーに名前呼ばれ会」 両部
  • MACROSS CROSS OVER LIVE 2日目 LV
  • 魔王様リトライ先行上映会
  • スフィア 「best friends」発売記念イベント第一部
  • リスアニ!LIVE SPECIAL EDITION ナツヤスミ 1日目
  • ワールドウィッチーズミュージックフェスタ2019 Premium Live Band Special 昼の部
  • 石原夏織 TEMPEST リリースイベント 「CARRY MEETING」東京 1,2回
  • LAWSON presents 雨宮天 第二回 音楽で彩るリサイタル 昼夜
  • 石原夏織SUMMER EVENT「TEMPEST MISSION」両部
  • Animelo Summer Live 2019 "STORY" 1日目
  • NANA MIZUKI LIVE EXPRESS 2019 千葉
  • LAWSON presents Sphere 10th anniversary Live tour 2019 “A10tion!” 中野2日目,愛知2日目,幕張1日目
  • LAWSON presents 夏川椎菜 1st Live Tour 2019 プロットポイント 中野1日目
  • バンダイナムコエンターテインメントフェスティバル 両日

2020

  • 石原夏織 1st LIVE TOUR「Face to FACE」 全公演
  • アニメ「魔法少女リリカルなのは」15周年記念イベント LYRICAL★LIVE DAY2
  • Afterglowスペシャトークイベント いつも通りの放課後デイズ
  • 石原夏織のCarry up&up!? 100回突破記念公開収録
  • 戦姫絶笑シンフォギアRADIO出張版 〜XD公開生配信UNLIMITED2020〜
  • LAWSON presents Sphere 10th anniversary Live 2020 “スフィアだよ!全曲集合!!いちにちめ/ふつかめ“
  • fhána Sound of Scene ONLINE "Pathos"
  • 1st LIVE TOUR「Face to FACE」BD・DVD発売記念オンラインイベント「CARRY COMMUNICATION+」7/11 1,2回目 8/1 1,2回目
  • 2ndアルバム「Water Drop」発売記念オンラインイベント「CARRY COMMUNICATION -Water Drop-」 9/5 1,2回目 9/12 1,2回目
  • 石原夏織 AUTUMN EVENT「ONE DROP」1,2,3回目
  • 小松未可子石原夏織のFUN'S PROJECT LAB 秋のオンライン生収穫祭 両部
  • 『どうにかなる日々』公開記念舞台挨拶 10/24 15:30開始
  • 『どうにかなる日々』公開記念舞台挨拶 第二弾 10/31 9:40, 11:45, 13:20, 15:30開始
  • SAO アリシゼーション -After War- 昼夜
  • LAWSON presents 麻倉もも Live 2020 "Agapanthus" 2日目
  • 石原夏織5thSG「Against.」発売記念オンラインイベント「CARRY MEETING -Against.-」 11/28 1,2回目 11/29 1,2回目 12/5 1,2回目
  • 東山奈央 10thアニバーサリーライブ「Special Thanks!フェスティバル」 2日目
  • LAWSON premium event スフィアのMusicRainbow07
  • fhána Sound of Scene ONLINE ”Ethos”
  • 小倉唯 ONLINEクリスマスライブ2020 〜Winter Twinkle Magic〜
  • 石原夏織のCarry up&up!? X'MAS SPECIAL 一部二部
  • ANIMAX MUSIX KOBE DAY2, YOKOHAMA
  • 第57回千葉大祭「石原夏織のcarry all before us!!」with 千葉大学声優研究会
  • 戸松遥 Resolution リリースイベント(ゲーマーズ)
  • UCHIDA MAAYA Zepp Tour 2019 「we are here」Zepp Tokyo 1回目
  • 「アルマギア -Project-」6thシングル「フォレストリンカネーション -diva. Tia & Kera- (cv.楠木ともり石原夏織)」リリースイベント
  • 冴えない彼女の育てかた Fine/大ヒット御礼舞台挨拶
  • fhana "where you are Tour 2019" -divine-
  • UVERworld KING'S PARADE 男祭り FINAL
  • 石原夏織 4th SG「Face to Face」発売記念イベント「CARRY MEETING–Face to Face-」東京 第一回1部2部,第二回2部
  • LAWSON premium event 戸松遥豊崎愛生,halcaのMusic Rainbow 06 1, 2回

2021

  • 近藤玲奈 1st LIVE 〜Listen〜 昼夜
  • fripSide Phase 2 : 10th Anniversary FINAL
  • 石原夏織 2nd LIVE 「MAKE SMILE」 昼夜
  • LAWSON presents TrySail Live 2021 “Double the Cape” 両日
  • 小松未可子石原夏織のFUN'S PROJECT LAB 春のオンライン研究会/発表会
  • 冴えない彼女の育て方 Fes. Fine ~glory moment~
  • 近藤玲奈1stシングル「桜舞い散る夜に」発売記念ネットサイン会
  • 石原夏織6thSG「Plastic Smile」発売記念イベント「CARRY MEETING –Plastic Smile-」 5/15 1,2回目 5/16 1,2回目 5/22 1,2,3回目
  • THE IDOLM@STER MILLION LIVE! 7thLIVE Q@MP FLYER!!! Reburn 2日目
  • 小松未可子「悔しいことは蹴っ飛ばせ」インターネットサイン会
  • ホリミヤ」Special Event「HARMONY PARK」 昼夜
  • 土岐隼一 Special Reading Live 2021 -True Gazer- 昼夜
  • 小倉唯 LIVE 2021 #ReLOVEcall
  • 石原夏織2ndLIVE「MAKE SMILE」Blu-ray&DVD発売記念オンラインサイン会 両日
  • 石原夏織2ndLIVE「MAKE SMILE」Blu-ray&DVD発売記念イベント「CARRY MEETING -MAKE SMILE-」 7/31 1,2回目 8/8 1,2回目
  • KIYONO YASUNO 10th Anniv. Billboard LIVE Tour 2021 ~Dear my Character Songs~ TOKYO夜
  • 石原夏織 SUMMER EVENT「Smile Go Happy」 昼夜
  • Animelo Summer Live 2021 "COLORS" 1,2日目
  • アニメひげひろを振り返るラジオ公開録音
  • LAWSON presents TrySail Live Tour 2021 "Re Bon Voyage" 横浜・東京2日目
  • A&Gオールスターオンライン2021
  • THE IDOLM@STER MILLION THE@TER WAVE 06&07 発売記念イベント
  • 人気声優「石原夏織」トコサタ生中継&トークショー
  • ANIMAX MUSIX 2021
  • プロジェクト東京ドールズ特別イベント
  • DIALOGUE+ LIVE TOUR 2021 「DIALOGUE+ 1」東京
  • さよなら、ティラノ初日舞台挨拶
  • 京Premiam Live
  • 石原夏織7thSG「Starcast」発売記念イベント「CARRY MEETING -Starcast-」 12/12, 1,2回目 12/19 1,2回目, 12/26
  • THE IDOLM@STER CINDERELLA GIRLS 10th ANNIVERSARY M@GICAL WONDERLAND TOUR!!! CosmoStar Land 初日
  • 石原夏織7thSG「Starcast」発売記念イベント「CARRY TALKING -Starcast-」

2022

2023

  • fhána New Year Live 2023 あけおめの集い
  • 高尾奏音の「かのんソナタ~第一楽章~」」成人式イベント
  • LAWSON presents TrySail Arena Live 2023 〜会いに行くyacht! みんなであそboat!〜 初日
  • THE IDOLM@STER M@STERS OF IDOL WORLD!!!!! 2023 両日
  • 石原夏織 2023カレンダー発売記念イベント
  • 東京ミュウミュウ にゅ〜♡スペシャルイベント Cat!!してSuperParty 昼夜
  • EJ My Girl Festival 2023
  • 輪廻のラグランジェ10周年&Blu-ray BOX発売記念上映会
  • 石原夏織 ファンクラブイベント「UNITY」vol.2 昼夜
  • Anime Japan 2023
  • UVERworld VS シリーズ day2:UVERworld vs Official髭男dism
  • LAWSON presents 令和5年度 417の日 1回目
  • 「スフィアの4 colors LABO」オフラインイベント~しーにゃんにゃんだよ!全員集合!! 昼夜
  • THE IDOLM@STER MILLION LIVE! 10thLIVE TOUR Act-1 H@PPY 4 YOU! 2日目
  • 寿美菜子豊崎愛生「さよなら中野サンプラザ音楽祭」
  • あもんぴーずのほんわかLIVE
  • 石原夏織のCarry up&up!? -5周年記念公開イベント- 両部
  • ラブライブ!蓮ノ空女学院スクールアイドルクラブ OPENING LIVE EVENT~Bloom the Dream~ 夜の部
  • TVアニメ『夢見る男子は現実主義者』先行上映会&トークショー
  • 美佳子@ぱよぱよ 公開録音 6月開催
  • 温泉むすめ トークイベント in 永田町(東京)両部
  • 戸松遥のココロ☆ハルカス&寿美菜子のラフラフ」番組コラボイベント2023 昼夜
  • LAWSON presents 朗読歌劇アルマギア ~First Live 2023~
  • LAWSON presents IDOLY PRIDE VENUS PARTY The First 1日目
  • 小倉 唯 Memorial LIVE 2023~10th Anniversary Assemble!!~ 夜の部
  • 戸松遥 ニューシングル「Alter Echo」発売記念オンラインリリースイベント リミスタ
  • UVERworld KING'S PARADE 男祭り REBORN at NISSAN STADIUM 6 vs 72000
  • LAWSON presents TrySail Live Tour 2023 "SuperBloom" 埼玉
  • 石原夏織 5th Anniversary Live -bouquet-
  • 戸松遥 ニューシングル「Alter Echo」発売記念リリースイベント 生電話
  • Animelo Summer Live 2023 "AXEL" 2,3日目
  • 石原夏織 11thシングル「Paraglider」発売記念イベント「トーク&個別お話し会」大阪・名古屋
  • 石原夏織トークショー石原夏織のK!O!Revolution!~
  • fhána 10th Anniversary SPECIAL LIVE "There Is The Light" + リハーサル見学ツアー
  • The QUEEN of PURPLE 2nd Live Tour Live and let "Live" 東京
  • 石原夏織近藤玲奈の帰ってきたふわふわーるど
  • 豊田萌絵観察バラエティ もえしツアーズ~もえバス乗換案内~ 第一部
  • 東京ミュウミュウ にゅ〜♡めがもるパ〜ティ〜♡ 昼夜
  • ホリミヤ -piece-」special event 『HALLOWEEN PARTY』 昼夜
  • 石原夏織 5th Anniversary Live -bouquet- Blu-ray 発売記念オンラインサイン会 1部2部
  • 京 Premium Live 2023 1日目
  • 本渡楓と天津向の「本渡上陸作戦」第4回 番組単独イベント 第一部
  • FC限定イベント「ふぁなみりーサミット 2023 Winter 〜年忘れクリスマススペシャル!の集い 〜」
  • UVERworld ENIGMASIS TOUR 横浜アリーナ ~TAKUYA∞生誕祭~
  • Ishihara Kaori Xmas Sweets Party 夜の部

2024

  • 坂本真綾 LIVE TOUR 2023「記憶の図書館」東京1日目振替公演
  • 石原夏織 5th Anniversary Live -bouquet- Blu-ray 発売記念イベント「トーク&お話し会」東京・大阪・名古屋
  • TVアニメ『ホリミヤ -piece-』Blu-ray&DVD第3巻リリースイベント
  • fhána “Beautiful Dreamer ASIA Tour 2024″ 東京
  • 石原夏織のCarry up&up!? 6周年記念公開イベント 1部2部
  • 市ノ瀬加那のかなナビ!1周年記念イベント 夜の部
  • 石原夏織ファンクラブイベント「UNITY」vol.03 大阪・東京昼夜
  • hololive 5th fes. Capture the Moment Stage 3
  • Anime Japan 2024
  • ANIMAX MUSIX 2024 SPRING

Node.jsでioredisを使っている人がenvoyのredis-proxyを通すときの注意点

どうも、お久しぶりです!

コッピーです。

表題の件について、かなり沼ったのでメモがてらブログに残すことにしました。

何があったか

そもそも注意点と書いているが、何があったのかという話です。

簡潔に言ってしまうと、ioredisのインスタンス生成時に

[ioredis] Unhandled error event: ReplyError: invalid request

というエラーが出て、Redisへの接続ができませんでした。

アプリケーション構成

上記の問題が発生した際の構成を以下に示します。

f:id:hmaa_ryo:20210920004103p:plain

ここで、各コンポーネントのバージョンなどは以下の通りです。

  • node.js: 13.5.0
  • redis: 6
  • envoy: 1.18.3

なお、これについては基本的にはどのバージョンでも発生する問題だと思っています。理由については読み進めていただければ分かると思います。

問題の詳細

Invalid request のエラーが起きたといっても、なぜそれが起きたかという話ですね。

これはenvoyのissueを見ていただけると同じ問題について上がっているのですが、ioredisではredisのステータスチェックにINFOコマンドを使っており、envoyのredis-proxyがINFOコマンドに対応していないため、INFOのリクエストを処理することができず、エラーが起きるということのようです。

ioredisの詳細

ioredisではインスタンス生成時にいくつかのオプションを設定することができます。その中で enableReadyCheck というオプションがデフォルトでtrueになっており、この設定がINFOコマンドでのステータスチェックを行う設定になります。

具体的な処理内容についてはコードを読んでいただければと思いますが、ざっくりと言うとINFOコマンドを叩いて、返ってきたレスポンスから loading: 0 だったらredisのチェックに成功するという処理です。

envoyの対応コマンド

envoyで対応しているコマンドについてはこちらです。

上のissueにもあるのですが、そもそもenvoyを通す時点で、アプリケーション側はどのredisに繋がるかが分かりません。envoyから先、どのredisに繋がるかが分からないということはINFOコマンドの結果が変わってくる可能性があるということです。

それを考えたとき、envoyのredis-proxyでINFOコマンドに対応しないのは自然だと思いますし、今後も対応することは無いのでは?と思っています。

解決策

envoyを通す以上、INFOコマンドを使うことができないため、どうしてもioredisを使いたいということであれば、インスタンス生成時に enableReadyCheck: false を渡して、INFOコマンドによるreadyのチェックを行わないようにすることで解決することができます。基本的にはenvoy側でredisへのhealthcheckはしていると思うので、ioredis側でわざわざreadyのチェックを行わなくてもあまり影響はないと思いますが、これをオフにするのが嫌だという場合にはioredisをやめて別の方法でredisへの処理を行うか、envoyを通さずにprimaryとreaderをredis側で明確に分けてあげるかだと思います。

参考文献

石原夏織さんのラジオに花を贈った話

さてさて,例によって技術ブログも書かずにオタクブログばかりを書いているコッピーです. 今回はタイトルの通り,花を贈ったので,その話を書いてみようかと思います.

経緯

経緯もなにも無いのですが,これは単に石原夏織さんの誕生日だったからです. せっかくなら何か贈りたいなぁとはこれまでも思っていたのですが,今がまさにその時なんじゃないかと! そう思った次第です.

実際に贈った花

実際にどんな花を贈ったの?ということで少し書いていこうと思います.

まず,今回絶対に譲ることができなかったのは「ジニア」というお花です. この花は石原夏織さんの誕生日である8月6日の誕生花の一つです.他にもアサガオなんかも誕生花になっているそうですが,今回ジニアを選んだのは花言葉が今の状況で伝えたい言葉にぴったりだったのが理由です.

ジニアの花言葉は「不在の友を思う」という言葉なのですが,昨今の新型コロナウィルス感染症の影響で,ライブやイベントなどは軒並み中止や延期,オンラインでの開催へと変わっていきました.

この中で当然僕もオタクとして多くのイベントへの参加機会が失われています.ですが,そんな中でもいつもラジオやSNSを通して元気をもらっていますと,またイベントが気兼ねなく出来るようになったら絶対に遊びに行きますと,そういう気持ちを伝えるのに「不在の友を思う」という花言葉がすごく自分の中でしっくり来たので,「ジニア」の花を入れたフラワーアレンジメントという形で贈らせていただきました.

そしてこれが実際に贈ったものになります.諸事情があって直接お花の写真を撮ることが出来なかったため,後に書く今回お世話になったお花屋さんの方に写真を撮っておいてもらい,その画面を撮影させていただきました.

f:id:hmaa_ryo:20200810235301j:plain
ジニアを使ったフラワーアレンジメント

僕の要望通り,暖色系をベースに赤色のジニアを使って作っていただきました!(本当はベースは石原夏織さんのイメージカラーでもある青色にする予定でしたが,この時期の花で上手く青色をベースに作るのは難しく,第二候補の暖色系ベースで作っていただきました)

正直,自分の想像していたよりもすごく綺麗で,素敵な仕上がりになっていて自分でもびっくりしました!

お世話になった花屋

さて,今回お世話になった花屋さんですが,四谷駅のアトレにありますプレジュールという花屋さんです.

花に関する知識0で,何も分からない自分にもすごく親切に対応してくださりました!

僕が何も考えていなかっただけですが,フラワーアレンジメントとして全面を強調したものにするか,どこから見ても綺麗なものにするのかという(恐らく)常識的な部分をどうするかを実際のものを見せてくださりながら教えていただきました.

ジニアも「赤」「オレンジ」「緑」などの色がある中で,絶対に赤が良いですとお伝えして,頑張って手配していただきました!

また,ベースになる色やお花について店員さんがわざわざ石原夏織さんのことを調べてくださり,どんな花にするのが良いのか考えてくれたりもしました!ひまわりが入ってるのとか,個人的にすごくきゃりさんにピッタリだなと思いました!すごい!!

写真を送ってもらうということはサービスとしてやってはいませんでしたが,無理を言って写真を撮っておいてもらい,後日お店に伺った際にお見せしていただき,こうしてiPadの画面を撮るという方法にはなりますが,記録にも残すことが出来ました.

そのおかげもあって,上に載せたような本当に素敵なフラワーアレンジメントになったと思います. 本当に今回このお店に頼んで良かったし,今後もお願いしたいと思いました!

まとめ

初めてのお花を贈るという経験はとても良いものになったと自負しております.

実際に「石原夏織のCarry up!?」が収録される日などは当たり前ですが分からないので,この花をきゃりさんが見る機会があるのかは分かりません(というのも次の収録までに枯れてしまう可能性もあるので).自分は誕生日に届くように贈らせていただきました.

ですが,きっと届くと信じてこの記事の締めとさせていただきます. 次はイベントでフラスタを贈るかな?w

石原夏織さんにプレゼントを送った話

どうもどうも,初回以来全く技術ブログを投稿していません,コッピーです.

そろそろ技術ブログを投稿しろよ!

とか聞こえてきてもおかしくない今日このごろですが,なんと今回は!!!

オタクブログです.

はい,そうです.残念ながら(?)オタクブログなんです.

タイトルの通り,今回は

石原夏織さんの1st LIVE TOUR「Face to FACE」でプレゼントを送った話をブログにしようと思います.

そもそも何を送ったか

今回自分はアルバムを制作してプレゼントさせて頂きました.

アルバムは,これまでのきゃりさんが演じたキャラクターのページや,他のきゃりさんファンにも協力してもらったメッセージページ,それから会場で撮った写真なんかをまとめたものを作った感じです.

なぜこんな企画をしたか

これなんですが,もちろん個人的な気持ちがいろいろあったからですが,

多分どう足掻いても自己満足の領域は出ない気がします笑

とは言え,書いてみるとこんな感じかと思います.

  • きゃりさんの初めてのツアーだったから
  • 自分にとっても初めてのツアー全通だったから

この2つが大きくて,何か記念になるものを残したいと思って企画をした感じです.

普段,ラジオなどでリスナーからのメールにすごく楽しく答えているきゃりさんを思い浮かべて,もっときゃりさんを笑顔に出来ないかな?とか喜んでほしいという思いで制作をさせていただきました.

アルバムにした理由

企画というと多分いろいろと手段があると思います.フラスタだったり色紙だったり...

今回,あえてアルバムにしたのは正直なところ自分の予算と知り合いの人数の兼ね合いが大きいです.

協力してくれる人が多くないと色紙はスカスカになったりして盛り上がらないですし,フラスタは純粋にお値段がそこそこ張るんですよね(とか言いつつ後述しますが,フラスタに参加はさせていただきましたが)

そんなところで,メッセージ以外でも内容を濃くしてボリュームを出せるアルバムにすれば,少ない人数でもそれなりに良いものが出来ると思ってアルバムにしました.

実際に出来たもの

こんな感じで最終的には仕上がりました(名前などは伏せてあります).

f:id:hmaa_ryo:20200226002410j:plain
きゃりさんをイメージしたイラスト
f:id:hmaa_ryo:20200226002511j:plain
キャラクターページ
f:id:hmaa_ryo:20200226002545j:plain
メッセージページ

このキャラクターページとメッセージページのセットが協力してくれた15人分まとまって,最後に集合写真を乗せたのが完成版になります.

出来栄え

個人的には結構よく出来てるんじゃないかと思っています.

特にイラストは知り合いに描いてもらったのですが,僕からは「Face to FaceのMVの衣装を着たCarry up!?のポーズをしたきゃりさん」というすごく雑な依頼をしただけなのですが,たくさん意見をくれて,どう描けばよりきゃりさんらしいかというのを突き詰めて,本当に可愛くて最高なきゃりさんを描いてくれました.

後日焼き肉を奢る予定ですが,こんなに素晴らしいイラストを描いてくれる友人がいてくれて幸せですね!

企画してみた感想

いかんせん自分にとっても今回初めて企画をするというところだったので,たくさん悩みました.

協力してくれる人からしたら,あの企画って今どうなってるんだろう?って気持ちになることがあるんじゃないか

なんて思って,なるべく進捗報告をしたほうが良いのかな?とか考えましたし,

もちろん自分の進んでる方向が協力してくれた方の向いてる方向と合ってるかな?っていう心配もありました.

なので,「今こんな感じで作ってるんだけど,飾り付けのマスキングテープはどうすると良いかな?」とか出来るだけ聞いたりして進めたのですが,もしかしたら完成版を見て楽しみたいというサプライズを期待していた人がいたら良くなかったかな?とかも思います.

この辺は正解はないと思いますし,自分でも合っていたのかは分かりませんが,少なくとも完成版を共有したときにたくさん「参加できて良かった」「想像してたより良いものになっててびっくりした」「自分がきゃりさんだったら,これをもらったら嬉しい」などのポジティブな言葉を貰えたので,企画して良かったなと思えました.

謝辞

さて,改めて協力してくれた皆さんには本当に感謝でいっぱいです.

今回こんなに素敵なものになったのは絶対に協力してくれた皆さんのお力だと思います.

自分だけでは到底こんなに上手くはいかなかったと思うので,この場を借りて「ありがとうございます」と気持ちを表明しておきます.

おまけ

フラスタを企画してくれて,参加させてもらえて嬉しかったです.

f:id:hmaa_ryo:20200226003810j:plain
参加させてもらったフラスタ

2019年を振り返って

どうもお久しぶりです.コッピーです.

前回のブログで「次回はSolrに入れたデータを使った応用をします」とか言っておきながら結局サボりにサボって何一つ投稿していなくて申し訳無さの極みです...

しかも今回のブログ,タイトルで分かる通りSolrの応用とは何ら関係のないただの年末のエモい記事でしかありません. 実際いつかちゃんとSolrの方も記事にはしたいと思いますので,今回はご容赦願います...

プライベート

とりあえず仕事とプライベート,そして卒業について別々に整理していきたいと思います.

最初のブログで自己紹介をした通り,僕はただのオタクでしかないのですが,今年はかなり充実したオタクライフを送れたんじゃないかと思っています.数えてみると,今年の通算イベント数は49と,ほぼ週一でイベントに行っている計算になります.ココ最近は同期からも「今週は何のイベントなんですか?」とか「イベント行きすぎてお金なくて塩舐めてそう」とか何だか色々言われるくらい楽しくイベントに参加出来ていてすごく良い一年だったと言えます.

僕がこんな生活ばかりしているので,同期も徐々に「ライブ楽しそう」や「行ってみたい」とも行ってくれますし,実際何人かをライブに連れて行って「また行きたい」と言ってもらえたのはオタク冥利に尽きるというものです!!

特に今年はスフィアの音楽活動再開だったり,石原夏織さんが様々なフェスに出るようになったりで僕の大好きな人達がたくさん活躍していた年だったのでこれが何よりの自分にとっての幸せでした.もちろん戸松遥さんの結婚には自分の思っていた以上のダメージがあったりもしましたが,それも含めて自分がどれだけ好きだったのかを再確認できたんじゃないかと思っています.

また,イベントだけではなく,ラジオでもたくさんメールが採用されました.

石原夏織のCarry up!?では自分の中で目標としていた年間10通採用,そしてふつおた以外の企画コーナーでの採用という2つの目標を達成出来てとても幸せでした.なぜかメールが採用されるたびにネタを生み出してしまい,石原夏織さんには35歳だと思われていたというのが一番のネタになりました笑

ですが,それを話の種にしてリリースイベントなどではお話が出来ましたし,リリースイベントでもラジオでも「いつもありがとうございます」というこれ以上ないくらい嬉しい言葉も貰いました!石原夏織さんマジ天使!みんなも石原夏織さんを応援していこうな!!

とまぁこんな感じで2019年はすごく楽しいオタクライフを送れたので,2020年もたくさんイベントに参加して楽しい1年にしていけたらと思っています.石原夏織さんのツアーや,スフィアの全曲ライブなどたくさんの最高of最高イベントがすでに決まっているので,また何かの形で感想などを書けたらいいですね

卒業

まだ卒業して1年も経っていないんだなという思いがめちゃくちゃ強いですね!

自分は幸いにも研究室にはすごく恵まれていたと思います.周りで聞いていると教授が好きじゃないという人も多いですが,自分にとっては一番尊敬出来る人は誰かと問われれば真っ先に教授の名前が出てくるくらいの本当に尊敬出来る人でした.同期や先輩とも定期的にアホみたいな飲みの場を開いていますし,自分にとって一番濃い時間だったのが研究室であるのは疑いようのない事実です.

そんな研究室では自分は再帰透過材という素材を使った研究をずっとしてきていたのですが,さすがに2018年のうちに研究内容が変わって時間の無い中で書き上げた修論のデキはそれはもうお察しというレベルなので修論発表の場でも他の研究室の教授からは言われたい放題の地獄でしたね...

ですが,自分のやっていた研究については何を聞かれても答えられるくらいの準備はしましたし,今でも一番頑張ったことは何かと言われれば研究だと言えるくらいにはやってきたつもりなので,興味のある人にはいくらでも教えれますよ笑

卒業とか書いといて結局ただの研究の話になっているけれど,まぁ卒業自体には何も感情がないもので,純粋に研究室最高だったぜってことですね笑

仕事

さて,次に仕事についてです.

自分はまだ新卒1年目なので,仕事では特に学びの多い1年だったと思います.

新卒研修

今さら新卒研修のことから書きますが,新卒研修では3ヶ月間みっちりと幅広い分野の技術について学ぶことが出来ました.Golangから始まり,ReactやKotlin,Swiftなどサーバサイドもクライアントサイドもしっかりと技術に触って,実際にものを作って学ぶことが出来ました.これだけにとどまらず,AWSの方から直接1週間AWSアーキテクチャについて学ぶことが出来たのも大きかったです.ここでかなりしっかりとAWSについて学んだおかげで実際に配属されてからもAWSについてはかなり理解した状態から入ることが出来ました!

他にもISUCONをやってみたり,CTFをやってみたり,みんなで輪読をしたりととにかく盛りだくさんな技術研修ですごく楽しかったです.

配属後

7月からは配属先に入り,実際の業務に携わっているわけですが,自分は検索チームに入ったため,メインでは検索技術について学んでいます.

と言えればいいのですが,実際には検索技術についてはもちろん学んでいるのですが,現在はk8sについて学ぶことが多いです.現在チームではオンプレに載っている検索のシステムをすべてAWSに移行するということを行っています.その中でSolrというステートを持つシステムをどう取り扱うかとなったときにk8sという選択肢が出てきたためです.個人的にまだk8sについては全然理解出来ていない部分が多く,このまま運用していけるのかという不安があるため,2020年はしっかりとk8sについて理解を進めて,安心安全に検索システムを提供できるような運用が出来たら嬉しいです!

検索システムについてももちろん学んでいるところで,Solrの使い方には少しずつ慣れてきたし,検索技術勉強会にも出来る限り参加するようにしています.実際,自分にとっての勉強の軌跡を残せたらという思いもあって始めたこのブログだったので,検索システムについては出来る限り学びを共有する場に出来たらと思っています(本当だよ).自分でプライベートでこういった技術をかじる時間をあまり取れていないため,どのくらいの頻度で学んで,更新していけるかは全く分かりませんが,少しずつ更新していけたらと思っています.

おわりに

ということで今回は一通りの2019年の振り返りをしてみました.

実際にはこんなブログでは書き残せないような激動の1年で,とても濃い内容だったと思います.上では書いていませんが仕事では本番環境でやらかしちゃった人Advent Calendarに残せるんじゃないかというやらかしもしてたりします.プライベートでももっともっと石原夏織さんやスフィア,様々なイベントについて語りたいくらいです.

そんな2019年,一番言いたいことは 今年は人の縁にすごく恵まれていた ということです.

オタク仲間しかり,会社の同期しかり,先輩にもすごく恵まれました.石原夏織さんにも認知されて本当に人の縁に恵まれました.

2020年もただのクソオタクでしかありませんが,どうぞよろしくお願いします. それではまたこのブログでお会いしましょう.バイバーイ!!

SolrでSlackの投稿検索をする

どうもコッピーです.

初ブログで言ったとおり,今回の目標はSolrを立てて,Slackの投稿データを全文検索できるようにすることです.

基本的にはこちらの本を読みつつやっています.どうでもいいですが,この本の著者の半分がメルカリで働いているらしいですね.

前提条件

  • Solrは公式のDockerイメージを使用してDocker環境に構築する
  • 今回,SolrにSlackの投稿データを投げる部分はRubyで書きました

以下,簡単に理由を記載しています.

まず,あまりローカル環境を汚したくなかった(Java系は色々インストールとかめんどくさい)ので,上記の書籍ではローカル環境でやっているところをDockerで動かしています.

また,Rubyを選んだのは自分が書き慣れていたからです.それだけです.とはいえあまりAPI周りをRubyで書いたことはなかったので地味に時間を取られましたが...

環境

  • OS: macOS Mojave 10.14.4
  • Docker: 18.09.2
  • docker-compose: 1.23.2
  • Ruby: 2.5.5p157
  • Solr: 8.1.1

各種環境は以上のようになっています.最新環境との違いはあまり無いはずなので,以下環境構築手順は最新環境の構築を前提として記述しています.

各種環境構築手順

以下,上記環境構築手順になります.

  • Docker

macの場合,Docker公式から落としてくる方法と,brewで入れる方法の2種類の方法で入れることが出来ます. おそらくどちらで入れても問題ないと思います.ここでは,簡単なbrewを使用する方法で入れたいと思います.

$ brew cask install docker

はい,これだけです.簡単ですね.ちなみにこれでdocker-composeについても自動で入るはずなので,以下コマンドでバージョン確認をしてみてください.このように出力されていれば問題ないと思います.

$ docker version
Client: Docker Engine - Community
 Version:           18.09.2
 API version:       1.39
 Go version:        go1.10.8
 Git commit:        6247962
 Built:             Sun Feb 10 04:12:39 2019
 OS/Arch:           darwin/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          18.09.2
  API version:      1.39 (minimum version 1.12)
  Go version:       go1.10.6
  Git commit:       6247962
  Built:            Sun Feb 10 04:13:06 2019
  OS/Arch:          linux/amd64
  Experimental:     false
  
$ docker-compose -v
docker-compose version 1.23.2, build 1110ad01

RubyについてはデフォルトでMacに入っていますが,デフォルトのRubyはクソなので今回はrbenvを使用して入れていきます.ここで,あくまで僕自身がRubyで書きたかったからRubyを使用しただけなので,各自得意な言語,使いたい言語があればそちらでやっていただければ問題ありません.その場合はここは飛ばしていただいて構いません.

rbenv自体はgitbrewで入れることになります.ここではbrewを使用して入れていきます.また,rbenvは裏でruby-buildを使用するため,ここで一緒に入れてしまいます.

$ brew install rbenv ruby-build

rbenvが入ったら,パスの追加をします.自分はzshを使っているため,zshrcに下記のようなコードを追加します.bashorfishの方はそれぞれにあった場所に追加してください.

export PATH=/usr/local/bin/bin:$PATH
export PATH=$HOME/.rbenv/bin:$PATH
eval "$(rbenv init - zsh)"

これが追加できたらsource ~/.zshrcで読み込んでください. これでrbenvrubyをインストールする準備が整いました.早速入れていきたいと思います.今回は2.6.0を入れたいと思います.

$ rbenv install --list
$ rbenv install 2.6.0
$ rbenv global 2.6.0
$ rbenv rehash

これでインストールが完了したはずなので,最後にrubyのバージョンを確認してあげましょう.

$ ruby -v
ruby 2.5.5p157 (2019-03-15 revision 67260) [x86_64-darwin18]

自分の環境では2.5.5なのでこんな感じですが,何かしらバージョンがこんな感じで出力されていれば問題ありません.

長くなりましたが,アンド結構雑ではありますが,環境構築については以上です.Solrについてはこのあと構築していきます.

Solrのコア用ディレクトリを作成

まず,コアと呼ばれる,Solrの検索集合を用意します.これはRDBでいうスキーマのようなもので,コアごとにスキーマ定義やクエリの設定が出来ます.Solrは1つのインスタンスの中に複数のコアを持つことができ,それぞれにインデックスを保持出来ます.

例えば,複数のサービスで同一プラットフォームの検索システムを使用する場合にサービスごとに検索したいフィールドが異なる・ランキングの算出方法を変えたいということがあると思います.

このとき,それぞれのサービスごとにコアを用意することで,同じ検索システムを使用していても異なる設定を適用することが出来るというわけです.

では,コア用のディレクトリを作成していきます.

$ mkdir data
$ sudo chown 8983:8983 data

Solrコンテナの構築

まず,docker-compose.yamlを用意します. 中身はひとまずこのように書いてください.

version: '2'
services:
  solr:
    image: solr:latest
    container_name: 'solr_test'
    ports:
     - "8983:8983"
    volumes:
      - ./data:/var/solr/data
    entrypoint:
      - docker-entrypoint.sh
      - solr-precreate
      - slackCore
    restart: always

これはほとんどSolr公式Docker Imageから持ってきています.

今回はdocker-compose.yamlの中身については触れることはしませんが,簡単に言うとSolrの最新バージョンを使用し,コンテナ起動時にslackCoreというコアを/var/solr/data配下に作成しています.

/var/solr/dataはSolrがコアを作成するディレクトリで,いつのバージョンかまでは/opt/solr/server/solr/mycoresに作成されていたようです.

あとはDockerを起動するだけです.

$ docker-compose up -d

これが無事成功したら,ブラウザでlocalhost:8983にアクセスするとSolrのホームを起動することができます.

このような画面が出れば成功です. まだcoreにはデータは何も入っていないので,検索などは出来ません.

スキーマ定義

では,まずはスキーマ定義をしていきます.

スキーマ定義はSolrにどのようなデータを入れるか,どの項目が検索できるか,表示する項目はどれかなどを定義するもので,Solrはスキーマ定義がなければ原則データを入れることも検索することも出来ません.

原則というのは,Solrにはスキーマレスモードが存在し,スキーマ定義をしなくてもインデクシングされたデータからスキーマを推測する機能があるためです.

しかし,今回はスキーマレスモードについては取り扱わないため,スキーマ定義をしていくことになります.

スキーマを定義する上で,今回はSlackAPIからデータを引いてくるため,その中のどのフィールドを使いたいかを考える必要があります.

自分は今回,

  • client_msg_id : 投稿ID(一意)
  • type : イベントの種類(投稿,リアクションなど)
  • ts : イベントの発生時間
  • user : イベントを行ったユーザ
  • text : 投稿本文

を定義しました.全部定義するのはさすがにダルいので,少しだけピックアップした形になります.詳細についてはSlackAPIの仕様を見た上で,個々人の使用したいフィールドをピックアップしてみてください.

スキーマ定義の流れ

使用するフィールドを決めたので,いよいよスキーマ定義をしていきます.まずは簡単にスキーマ定義の流れを把握して,それから定義していきましょう.

スキーマ定義に必要なのは フィールドフィールドタイプ の2つです.フィールドは先程決定したclient_msg_idtextのようなもので,検索対象のデータのタイトルや本文などを格納する,Solrへの入れ物となるものです.それぞれのフィールドに対してどのような型(数値,文字列,日付など)であるかを定義したものがフィールドタイプです.

フィールドタイプについては基本的にデフォルトで用意されているもので十分であるため,今回定義することはしません.

スキーマ定義には大きく2つの方法があり,一つ目はschema.xmlを直接編集する方法です.もう一つはSchema APIを使用して定義する方法で,今回は後者のSchema APIを使用して定義する方法を採用しています.

フィールドの定義

では,フィールドの定義をしていきましょう.先程書いたようにAPIを使用して定義していくため,JSONファイルに記述していきます.

定義の方法は次のようにします.

{
    "追加or更新or削除を指定するキー": {
        "name": "フィールドの名前",
        "type": "フィールドタイプの名前",
        "オプション": "オプションの値"
    }
}

フィールドの追加,更新,削除の場合で記述が異なります.ここで指定できるキーは下記の通りです.

キー名 説明
add-field 追加時
replace-field 更新時
delete-field 削除時

基本的には登録時にはadd-fieldしか使いませんが,ユニークキーの設定のために一部replace-fieldも使用します.これについては後ほど説明します.

次に設定項目についてです.書き方からおそらく分かると思いますが,nametypeは必須項目です.オプションも含め,設定項目について簡単にまとめました.

項目名 説明
name(必須) フィールドの名前 半角英数字
type(必須) フィールドタイプの名前 フィールドで使用する型
indexed(オプション) true/false 検索可能なフィールドであればtrue.デフォルトはtrue
stored(オプション) true/false 検索結果として表示したい場合にはtrue.デフォルトはtrue
multiValued true/false 複数の値を登録する場合にはtrue.デフォルトはfalse

これ以外にも設定は可能ですが,今回は使用する範囲のみでまとめさせていただいています.もっと詳しく知りたい方は調べてみてください.

今回は下記のように(schemaDefinition.jsonとして)設定しています.

{
    "replace-field": {
        "name": "id",
        "type": "string",
        "indexed": "true",
        "stored": "true",
        "multiValued": "false"
    },
    "add-field": {
        "name": "type",
        "type": "string",
        "indexed": "false",
        "stored": "true",
        "multiValued": "false"
    },
    "add-field": {
        "name": "ts",
        "type": "string",
        "indexed": "false",
        "stored": "true",
        "multiValued": "false"
    },
    "add-field": {
        "name": "user",
        "type": "string",
        "indexed": "false",
        "stored": "true",
        "multiValued": "false"
    },
    "add-field": {
        "name": "text",
        "type": "text_ja",
        "indexed": "true",
        "stored": "true",
        "multiValued": "false"
    }
}

idについては既存フィールドであるため,replace-fieldを使用しています.この項目はユニークキーとなるため,検索・表示ともにtrueとし,multiValuedfalseとしています.必ず設定しなければいけないということはありませんが,ユニークキーを設定することで,データを取り込んだときに同一データを抜いて差分のみの取り込みが可能となるため今回は設定しています.

また,今回基本的に検索可能なフィールドは投稿本文のみとしています.検索可能なフィールド(日本語データが保存される場合)ではフィールドタイプにtext_jaを設定します.このフィールドタイプは裏でいい感じに形態素解析をしてくれます.この辺についてはSolr AdminでAnalysisを使ってみると分かりやすいと思います.

jsonファイルの準備も出来たので,APIを使用してフィールド定義を適用します.

$ curl -X POST -H 'Content-type:application/json' --data-binary @schemaDefinition.json http://localhost:8983/solr/slackCore/schema
{
  "responseHeader":{
    "status":0,
    "QTime":1319}}

上のようなレスポンスが返ってこれば成功です.これでフィールドの登録が出来ました.次はいよいよSlackの投稿データを流し込んでいきます.

SlackAPIのトークン取得

Slackの投稿データを流し込もうにも,SlackAPIを使用できるようにしなければいけません.

まずは

https://api.slack.com/apps

ここでSlackアプリを作成します.アプリを作成したら

Add features and functionality -> Permissions -> Select Permission Scopesからchannels:historyを選択します. これで保存していただければOAuth Access Tokenからトークンを取得出来ます.

また,ここでついでに投稿を取得したいチャンネルのIDについても取得しておきましょう.こちらは特にAPIを叩く必要もなく,Web上でSlackを開いたときにURLの最後の/以下の文字列がチャンネルIDです.

これで投稿データを流し込む準備が出来ました.あとはデータを流し込むだけですね!

Slack投稿データの流し込み

Slack投稿データについては先程取得したトークンを使用すれば簡単に取ってこれます.今回はRubyでプログラムを作成したのでプログラムの中で

  1. Slack投稿データの取得
  2. Json生成
  3. SolrへのAPI経由でのデータ流し込み

までやっています.ひとまず下にコードを載せておきますので,こちらを参考にしてください

@Update 2019.08.27 一部プログラムにミスがあったので修正

require "slack"
require "json"
require "net/http"
require "uri"
require "dotenv"

# .envファイルから環境変数を読み込む
Dotenv.load

Slack.configure do |config|
  config.token = ENV["TOKEN"]
end

# これで指定したチャンネルの投稿を取得できる
messages = Slack.channels_history(channel: ENV["CHANNEL_ID"])['messages']

# 必要なフィールドのみで新しい配列を生成
messageArray = messages.map do |message|
  messageHash = {}
  if message["client_msg_id"] != nil
    messageHash["id"] = message["client_msg_id"]
    messageHash["type"] = message["type"]
    messageHash["ts"] = message["ts"]
    messageHash["user"] = message["user"]
    messageHash["text"] = message["text"]
  else
    next
  end

  messageHash
end

# ここ以降でSolrへのデータ注入
uri = URI.parse("http://localhost:8983/solr/slackCore/update?commit=true")
http = Net::HTTP.new(uri.host, uri.port)
req = Net::HTTP::Post.new(uri.request_uri)
req["Content-Type"] = "text/json; charset=utf-8"
req.body = messageArray.compact.to_json

res = http.request(req)

puts res.code, res.msg, res.body

コード自体は難しいものでもないのですが,Solrに流し込む上で注意しなければならない点があるため,そこを説明していきたいと思います.

SolrにAPI経由でデータを流し込むとき,流し込むデータ全体を大カッコで囲う必要があります.そこで,プログラムの中で取得した投稿データのうち必要なフィールドのみをハッシュとして整形した上で配列に格納しています.

分かりやすいように例をあげておくと,Solrに流すときにはデータは下のような形になっています.

[
    {
        "id": "1234",
        "type": "message",
        "ts": "123456.789",
        "user": "1234",
        "text": "テスト"
    },
    {}...
]

また,Slack上ではclient_msg_idとなっているIDをidとして保存しています.これはフィールド定義のときにユニークキーとして使用するためにidという名前で定義したためです.

あとはこのコードを実行するだけです.コードをgetSlackMessage.rbという名前で保存して,実行してみましょう.下のように200 OKが返ってこれば成功です.

$ ruby getSlackMessage.rb
200
OK
{
  "responseHeader":{
    "status":0,
    "QTime":376}}

データの検索

さて,これでやることは全て終わりました.Solr Adminの確認をしてみましょう. Solr Adminで今回作成したコアを選択し,Queryを選んでください.ここで,何も変更を加えずにExecute Queryを押してみてください.

どうですか?投稿データの検索が出来たでしょうか? 何も変更していなければ全てのフィールドに対して全てのワードで検索をするという動作をしているため,登録したドキュメント全ての検索が出来ているはずです.

qとなっている部分をtext:検索したいワードとして再度Execute Queryを押すと検索したいワードでの検索が出来ます.

まとめ

以上,少し長くなってしまいましたが,Slackの投稿データをSolrを使って検索することが出来ました.

自分自身初めてSolrを触ってここまで出来るとかなり面白く,やりごたえもありました.

これを機に少しでも検索に興味を持ってもらえれば嬉しいです. 次回はこのデータを使ったちょっとした応用をしてみたいと思います.

今回使用したRubyのプログラムは下記GitHubに上げておきます. https://github.com/Kryota/slackSearch

参考文献