谷本 心 in せろ部屋

はてなダイアリーから引っ越してきました

ソニー銀行を住信SBIネット銀行と比べ始めて1年経ったのでメモ。

こんにちは、最近ツイッターのフリートでは株の話しかしてない @cero_t です。

もともと住信SBIネット銀行(以降SBI銀行)のユーザーだったのですが、外貨を扱うことが多いならソニー銀行の方が得かも知れないと気づき、ちょうど1年ほど前にソニー銀行の口座を開設しました。
それ以降、それぞれのメリットなどをメモしていたのですが、1年経ったのでブログにまとめておくことにしました。

先にまとめ

先に結論を書いておきますね。

  • 国内利用が中心で、振り込みをする機会が多いなら、SBI銀行の方が便利
  • 海外利用が多いか、外貨受取をする機会が多いなら、ソニー銀行の方が便利
  • 両方とも口座を作って、国内はSBI銀行、外貨はソニー銀行、という使い分けでもOK

住信SBIネット銀行のほうが良いところ

まずはSBI銀行の良いところです。

ATM手数料と振り込み手数料の無料回数が多い

SBI銀行は残高に応じて「スマプロランク」と呼ばれるランクがつき、それでATMの無料利用回数や振り込みの無料回数が変わる仕組みになっています。たとえば残高が30万円以上ならランク2、300万円以上ならランク3になります。 ランク2ならATM利用は月5回、振り込みは月3回まで無料。ランク3ならいずれも月7回まで無料です。

スマプロランクについて | スマートプログラム | NEOBANK 住信SBIネット銀行

ソニー銀行は同様に「Club S」という仕組みがあり、最初はステージなし、残高300万円以上などでシルバーになります。
ステージなしならATM利用は月4回、振り込みは月2回まで無料。シルバーならATM利用は月7回、振り込みは月4回まで無料です(SONY Bank Walletカード作成する前提)

優遇特典|優遇プログラム Club S|MONEYKit - ソニー銀行

表にまとめておきます。

残高が30万円以上、300万円未満の時
SBI銀行 ソニー銀行
ATM無料利用回数 5 4
振り込み無料回数 3 2
残高が300万円以上の時(※残高300万円未満でも他の条件を満たせばこのステージになる)
SBI銀行 ソニー銀行
ATM無料利用回数 7 7
振り込み無料回数 7 4

ATMも振り込みも、月に7回使えれば、まず困ることはないですよね。

毎月の自動振り込み機能がある

SBI銀行は、毎月決まった日に他の口座へ自動的に一定額を振り込むことができます。
たとえば給与口座がSBI銀行で、他のローンやクレジットカードなどの支払い口座があったとして、そちらの口座振り込むことができます。
僕はうっかり住宅ローンの口座に振り込むのを忘れて残高不足になることが度々あったので、この機能はかなり重宝しています。

他の銀行でもこの機能を使えるところはありますが、ソニー銀行にはありません。

米ドルへの両替が安い

SBI銀行、ソニー銀行のいずれも、円だけでなく外貨の口座を持つこともできます。
為替手数料もかなり安いため、外貨貯蓄をしたいとか、FXをするほどではないけど外貨の現物を売り買いして稼ぎたいとかの用途に使いやすいです。

ソニー銀行と比較した時のSBI銀行の強みは、円をドルに替える際の手数料が「1ドルにつき4銭」と非常に安いことです。
たとえば通常のクレジットカードで外貨支払いをする際の手数料は1.6〜2%ですから、その表現で言うと0.04%程度ということになります。文字通り桁が違いますね。
銀行窓口や空港での両替手数料はもっと高いことも多いので、さらに差がつくでしょう。

米ドルでの支払いも安い(ただし年間30回まで)

SBI銀行が発行するデビットカードである「ミライノデビット」はドルで払う際にドル口座の残高から支払うことができます。上に書いたとおり通常のクレジットカードに比べて安い手数料で両替したドルで払えるわけです。
また、円高の際にドルを買っておいて、その後に円安になっても保有しているドルで支払うことができるわけです。もちろん逆のパターンもありますけどね、ワハハハハ(笑い事ではない)

ただ少しルールが複雑で、ミライノデビットを利用してドル口座から支払う場合、1回の決済につき2.8%の手数料が掛かります。これは通常のクレジットカードの為替手数料を優に超える手数料です。
しかし、この手数料は年に30回まで、同額のポイントでキャッシュバックを受けることができます。

分かりにくいのですが、要するに年間30回までの支払いであれば掛かる手数料はあくまでも1ドルにつき4銭だけで、それを超えると1ドルにつき3円近い手数料が発生してしまうということです。

海外旅行で頻繁に使っていると30回を超えてしまうので、たまに米Amazon.comで買い物をするとか、海外旅行中でも大きめの買い物をする時に限り使うなど、用途を絞った方が良いでしょう。

JALのマイルが貯まる

SBI銀行やミライノデビットの利用で貯まるポイントは、JALのマイルと交換することができます。

スマプロポイントについて | スマートプログラム | 住信SBIネット銀行

ただマイル還元率はあまりよくないため、効率よくマイルを貯めたいのであれば、後述するJAL Global WALLETやJAL NEOBANKの利用を検討したほうが良いでしょう。

余談: JAL GLOBAL WALLETとJAL NEOBANK

SBI銀行はJALと提携していて、SBI銀行の外貨口座から円や外貨をチャージして利用できるJAL Global WALLETというプリペイドカードを発行しています。また、外貨預金や外貨積み立てでマイルが貯まるJAL NEOBANKというサービス(SBI銀行のJAL支店という位置づけ)も提供しています。
いずれも年会費などは掛からず、SBI銀行やミライノデビットに比べて効率よくマイルを貯めることができます。

ただ、いずれのサービスも現時点ではあまり使い勝手が良くないため、僕は利用していません。

ソニー銀行のほうが良いところ

続いて、ソニー銀行の良いところです。

11種類の外貨決済に対応

ソニー銀行デビットカードである「Sony Bank WALLET」は、11種類の外貨口座からの支払いに対応しています。SBI銀行のミライノデビットは米ドルにしか対応していません。 なのでヨーロッパやオーストラリアにも旅行するなら、Sony Bank WALLETのほうが便利に利用できます。

為替手数料はClub Sのステージにもよるのですが、SBI銀行の為替手数料と大きくは変わりません。通常のクレジットカードや銀行での両替に比べれば1/10くらいの手数料です。

為替コスト(手数料)・金利 | 外貨普通預金 | 住信SBIネット銀行

優遇特典|優遇プログラム Club S|MONEYKit - ソニー銀行(ページ後半の「為替コストの優遇」)

米ドルに関して言えば、Club Sのステージなしで15銭、シルバーなら10銭ですが、SBI銀行では1ドル4銭と安くなっています。
プラチナステージまで到達すれば1ドルにつき4銭になりますが、到達するのが大変ですね。

外貨での支払時に手数料が掛からない

Sony Bank WALLETでは、外貨口座から支払う際の手数料などは掛かりません。SBI銀行のミライノデビットでは、先に述べたとおり1回の決済につき2.5%の手数料が掛かります(ただし米ドルは30回まで同額をキャッシュバック)

Sony Bank WALLETのほうが、ドルも含め、普段の外貨支払いとして利用しやすいと言えます。

ANAのマイルが貯まるSony Bank WALLETがある

Sony Bank WALLETは国内で利用すると通常0.5〜2.0%のキャッシュバックがあるのですが「ANAマイレージクラブ / Sony Bank WALLET」というサービスに加入すると、キャッシュバックの代わりにANAのマイルをもらうことができます。いや、もうちょっと良い名前にできなかったんですかね。

ANAマイレージクラブ / Sony Bank WALLET 商品詳細説明書|MONEYKit - ソニー銀行

ANA版のSony Bank WALLETでは200円の利用につき1マイルの還元があり、マイル還元率0.5%になります。ちなみにANAカードではマイル還元率が1.0%くらいになるので、きちんとマイルを貯めている人にとってはあまり魅力はないですね。
また外貨預金や外貨の定期預金でもマイルが貯まり、たとえば3万ドル(≒300万円分)を1年間の定期預金にすると、年間で2520マイル貯まります。元々の為替手数料が低いことも踏まえると、この外貨貯蓄でマイルが貯まるというのはANA派にはなかなか良いですね。

外貨受取の手数料が掛からない

これは刺さる人には非常に刺さる話なのですが、ソニー銀行では、海外から送金された外貨を受け取る際の手数料が掛かりません。多くの銀行では数千円の手数料が取られます。
SBI銀行でも2500円前後の手数料が掛かるため、たとえば10000円分の外貨が送金されても7500円前後になるのですが、ソニー銀行では満額を受け取ることができます。

頻繁に外貨を受け取ることがある人は、その目的だけでもソニー銀行の開設にメリットがあると思います。

硬貨での入金ができる

これは非常にマイナーな話なのですが、ソニー銀行では三井住友か三菱UFJのATMから硬貨での入金ができます。SBI銀行ではできません。

僕はふだん小銭入れのない財布を使っていて、発生した小銭はポケットなどに入れて持ち帰って貯金箱に入れておき、たまに銀行に持って行くのですが、SBI銀行には入金できないのです。 まぁそんなマイナーな問題で困る人はあまり多くないと思いますが。

両方の銀行に共通すること

最後に、両方の銀行に共通するけど、他の都市銀行地方銀行にはあったりなかったりする特徴を整理しておきます。

毎月の自動入金機能がある

他の銀行の口座から、SBI銀行やソニー銀行の口座に毎月定額の振り込みをする機能です。
振り込みなので手数料が掛かるのかなと思いきや、手数料は掛かりません。

僕は都市銀行に給与口座を一つ持っているのですが、そちらの銀行からSBI銀行に毎月入金して、残高を集約しています。

対象外の外貨は受け取れない

SBI銀行、ソニー銀行とも、外貨送金で受け取れる通貨は決まっており、それ以外の通貨は受け取ることができません。
たとえば突然インドネシアルピアの送金を受け取ることになった場合には、都市銀行地方銀行の口座が必要になります。

住民税などの支払い口座に設定できないことがある

住民税の口座振替などのレガシーな口座振替は、都市銀行や一部の地方銀行、ゆうちょ銀行しか対応していないことがあります。
ネット銀行1本でいこうと思って他の口座をすべて閉じたりすると、そういう時に困ってしまうので注意してください。

まとめ

まとめると、振り込み回数や自動振り込みの利便性が強いSBI銀行、海外利用に強いソニー銀行、という整理になりました。
海外利用が少ないならSBI銀行のみでも良いでしょうし、振り込みをあまり使わないならソニー銀行のみでも良いでしょう。
あるいはJALのマイルを貯めているからSBI銀行、ANAのマイルを貯めているからソニー銀行、という選択もできます。

僕はJAL/ANA両方のマイルを貯めていますし、国内でも海外でも利用するので、これからも両方の銀行を併用し続けると思います。

いかがでしたか?


あ、このブログを読んで(読まなくても)ソニー銀行を開設しよっかなという気持ちになった人は、2000円 or 4000円がもらえる紹介キャンペーンに招待するのでお知らせください。

ご家族・ご友人 紹介プログラム|MONEYKit - ソニー銀行

紹介すると僕の方も1500円もらえるので嬉しいです!

4Kディスプレイのサイズと解像度の関係を改めて調べてみた。

皆さんこんにちは、調べてみましたブログです。

要約

先に本文の内容をまとめておくと、こんな感じです。

  • 4KディスプレイをPCディスプレイとして利用する場合、通常は4Kネイティブではなく拡大して利用する
    • 21〜23インチの4Kディスプレイは、1920 x 1080(200%拡大)で利用する人が多い
    • 27インチの4Kディスプレイは、2560 x 1440(150%拡大)で利用する人が多い
    • 32インチの4Kディスプレイは、Macなら3008 x 1692、Windowsなら3072 x 1728(125%拡大)で利用する人が多い
    • 41インチぐらいなら4Kネイティブで利用できる
  • Retinaディスプレイは、実解像度の1/2の疑似解像度で使うのがベスト
    • 21.5インチは、4K(3840 x 2160)を1920 x 1080(200%拡大)で使うのがベスト
    • 27インチは、5K(5120 x 2880)を2560 x 1440(200%拡大)で使うのがベスト
    • 32インチは、6K(6016 x 3384)を3008 x 1692(200%拡大)で使うのがベスト

はじまり

今年の春頃、みんながリモートワークを始めるに伴い、ディスプレイやアームを買っているのを見ていると、ついついうらやましくなってしまい、僕も27インチの4Kディスプレイを買いました。MacBook Pro 16に繋いで問題なく使ってたのですが、ふと、自分が2560 x 1440(WQHD)相当の疑似解像度で使っていることを思い出しました。
せっかく4Kディスプレイなのだから、4K解像度にしたほうが良いのかなと思って、3840 x 2160にしてみたら、いやー、文字が小さくて読めない読めない。27インチでこのサイズは無理だ。もっと大きなディスプレイが必要だ、という気持ちになりました。

どれぐらいのサイズが必要なのだろうかと思い、サッと比で計算すると40.5インチのディスプレイが必要だということになり、ちょっとデスクで使うには大きいですね、という気持ちになります。でも、本当にこの計算が合ってるのかな? と思い、ちょっと調べてみることにしました。

Macの疑似解像度と、Windowsの解像度表記

そもそも解像度とか疑似解像度と言われるものが何だか分からなくなってきたので、整理することにしました。

Macの場合、ディスプレイの解像度は「疑似解像度」(英語表記の場合は Looks like)で表現されます。たとえば僕の持っている4KディスプレイをMacBook Proに接続した場合、疑似解像度の選択肢は次の5つになりました。( )内は4Kを標準とした場合の倍率です。

  • 1920 x 1080(200%)
  • 2560 x 1440(150%)
  • 3008 x 1692(128%)
  • 3360 x 1890(114%)
  • 3840 x 2160(100%)

一方、Windowsの場合は「解像度」と「テキスト、アプリ、その他の項目のサイズを変更する」という2つで表現します。後者は、100%、125%、150%、175%、200%、225%、250%、300%、350%となっています。
MacWindowsの刻み方を比較すると、100%、125%(128%)、150%、200%の辺りは共通ですね。

つまるところ、現代の高解像度ディスプレイはDPI(インチあたりのドット数)が高すぎて、そのままだと文字が小さくて読みづらいため、文字を拡大する(その代わり、フチを滑らかに表示する)ようにしています。それでWindowsではパーセント表記で拡大率を表現する一方、Macでは疑似解像度という名前で表示の大きさを決めていて、つまるところMacでもWindowsでも、表現の仕方こそ違えどやっていることは同じでした。

Appleのサイトで製品を見てると

疑似解像度について少しググって調べてみると、こういう風に説明されていました。

上記で”2倍”と書いたが、Retina採用MaciPhoneiPadなどはMacBook無印などの例外を除けば全てネイティブ解像度はデフォルト設定の擬似解像度のちょうど縦横2倍になっている。
ではなぜデフォルトの値が2倍なのかというと、モニターというものはスケーリングした際に整数倍の表示にする時が一番ボケにくく鮮明な表示が可能になるからだ。
Macで4Kモニターを使用した際のRetina解像度 | INFORNOGRAPHY

なるほど、そういうものなのかと思い、AppleオンラインストアMacのオプション製品を調べてみることにしました。

27インチなら5K

まず、27インチRetinaディスプレイはこれが紹介されています。 www.apple.com 解像度は5Kです。前に見た時は「27インチで4Kを表示する時でも拡大するのに、5Kにしたところでさぁ・・・」と思っていましたが、このディスプレイの解像度は5120 x 2880で、ちょうど2560 x 1440の2倍になっています。
27インチディスプレイは、2560 x 1440相当で使うのがちょうど良い、という体感も照らし合わせると、そのちょうど2倍の解像度で提供するというのは納得がいきます。ちなみに27インチiMacも同じ解像度でした。

32インチなら6K

そして、値段が高いと評判の32インチRetinaディスプレイですが、こちらは6Kです。 www.apple.com この6016 x 3384という解像度は、3008 x 1692のちょうど2倍になります。つまり32インチでは、3008 x 1692の疑似解像度で使うと良いというのがAppleの考え方なのでしょう。

4Kは21.5インチ

ちなみに、iMacは21.5インチ版は4Kディスプレイ(あるいはフルHDディスプレイ)となっています。 www.apple.com 比率的にも、確かに21.5インチがちょうど良いと思います。

ただ、ディスプレイ単体としてはなぜか23.5インチの4Kディスプレイが紹介されていますね。 www.apple.com この辺りの不統一な感じはよく分かりませんが、視力が良くないなどで少し大きめに表示されて欲しい場合には、23.5インチ4Kが良さそうですよね。

4Kディスプレイユーザーの声も拾ってみる

「4K 27インチ 125% 150%」みたいな雑なキーワードでググってみて、世の中のWindowsユーザーがどういう倍率で表示しているかを調べてみました。
結果、どうやら27インチを使っている人は150%、32インチを使っている人は125%が多いようでした。

ここまでの話を整理すると、こんな感じです。

  • 21.5インチ or 23.5インチ
    • Appleストア: 4Kの200%表示で、1920 x 1080
    • Windows: 4Kの200%表示で、1920 x 1080
  • 27インチ
    • Appleストア: 5Kの200%表示で、2560 x 1440
    • Windows: 4Kの150%表示で、2560 x 1440
  • 32インチ
    • Appleストア: 6Kの200%表示で、3008 x 1692
    • Windows: 4Kの125%で、3072 x 1728

どうあれOSに関わらず、皆さんほぼ同じぐらいの(疑似)解像度で利用しているようです。

まとめ

そんなわけで、いま27インチディスプレイを2560 x 1440相当で使っていることは妥当であり、これを32インチに変えたところで程度の差はあれど拡大して使うことに変わりはないということが分かりました。

それならAppleオススメのLGの27インチ 5Kディスプレイにすれば綺麗になるかな、と思いましたが、こちらはHDMI入力がありません。Mac専用ディスプレイにするなら良いのでしょうけど、家庭用ゲーム機などを接続できなくなってしまうのは、ちょっと困ります。

じゃぁいっそ4Kネイティブで使える42インチ 4Kディスプレイを買えばネイティブ解像度で使えるから良いよね、と少し血迷いましたが、机から買い直しになるし、別にそこまで大きいものが欲しいわけじゃないしさすがにね、という気持ちになりました。

というわけで、安心して「何も買わない」という結論が出た、今回の調査でした。

いかがでしたか?

レンタルすべる人の引き合いがない件について。

前に、オファーズさんのサイトでこんな記事を書きました。

offers.jp

主題は副業だったはずなのですが、なぜかタイトルに「レンタルすべる人」が入ってしまい・・・w

いやぁ、1件も引き合いないですね、レンタルすべる人。ただの冗談にしか見えないでしょうから、引き合いなんてあるはずもないわけですが。
ただ実際、こういう形のビジネスってわりとありだと思うんですけど、どうなんですかね?


だいたいどこの現場でも、スキルがある人は不足しています。
僕自身、コンサルティングやアーキテクトのような形で案件に参画することが多い(多かった)のですが、だいたい最初は特定領域や特定製品に特化する名目で参画するものの、だんだんと案件全体の様々な技術について意見を求められるような役割になっていく、ということが非常によくあります。
恐らくどこの会社や組織でも、そういう意見が出せる・判断ができる人が足りていないというのが現状なのだと思います。

一方で、いまは副業を解禁する企業も増えていますし、フリーランスや独立して働くエンジニアも目立つようになっています。スキルがある人たちはだいたい引き合いがたくさん来るようで、参画して欲しいと打診をしても、大抵しばらく先まで埋まっている感じです。
また費用面で言うと、日当4万円とか7万円というのは国民の理解を得られないそうですが *1 スキルのある人たちは全く国民の理解を得られない単価になっていると思いますw

そういう諸々の状況を踏まえると

  • 月5-10万円など、それなりにリーズナブルな値段でチャットに常駐するだけ
  • 質問する側は、気軽に技術的な相談ができる
  • エンジニア側は、空いた時間でそれに回答する

という形のサービスって、双方にとってメリットが大きいように思うのですよね。質問する側にとっては調べる・判断するのに時間が掛かることでも、スキルのあるエンジニアにとっては簡単に回答できる場合なんてザラにあります。もちろん、質問が増えてくれば値段を調整すれば良いわけですし、もっと大きな案件を始めるときには本格的に参画してもらっても良いわけです。

「外部技術顧問」みたいな大げさな名前をつけなくても、こういう緩い形で契約するはアリだと思うのですよね。いまはリモートワークが中心の会社も増えていることを踏まえると、チャットに常駐するだけのサービスというのもちょうど良いでしょうし。

そういう「緩さ」が大事なんじゃないかと思っての「レンタルすべる人」という命名なんですよね。


そんなわけで、ジョークみたいな名前のレンタルすべる人ですが、それなりに合理的で面白い仕組みだと考えています。
興味があるよって方がいましたら、ぜひツイッターなり何なりでお知らせください!

100万件ぐらいのレコードを扱ったらOOMEが出た話。

要約

技術的な話だけ教えて、という方のために先に結論だけ書いておきますと、PostgreSQLはクエリを実行した時点で全レコードの情報を一気に読んできてヒープを埋めてしまう場合がある、ということ話です。
たとえば、ResultSet#nextメソッドを使いながら処理を回すようなコードを書いて、少ないヒープでも処理できるようにするのは常套手段だと思いますが、そういうコードを書いていても一気にヒープを消費してしまうことがあるのです。詳しくはこのドキュメントを見てください。

https://jdbc.postgresql.org/documentation/head/query.html#query-with-cursor

ことの発端

ちょっと仕事でJava + jOOQ + PostgreSQLで、DBのデータを集計するようなバッチ処理を書いてまして、もちろん俺様の書いたコードにバグなんてあるはずがないわけですが、念のために性能試験をしておこうと思い、100万レコードのサンプルデータを投入してバッチのテストを走らせたら、OutOfMemoryErrorが起きたんですよ。

OutOfMemoryError。まさか、俺が?

戸田奈津子の字幕っぽいセリフが頭をよぎりつつ、何度か試してみてもやはりOutOfMemoryErrorが起きてしまいます。ヒープを2GBとかにすれば実行できますし、レコード数を50万とかに減らせば問題なく動くのですが、そもそも何万レコード扱おうがヒープを大量確保するようなコードなんて書いていないつもりだったので、真面目に問題を確認することにしました。

何がヒープを埋めているって言うんだい?

僕も素人ではないですから、即座に起動引数に -XX:+HeapDumpOnOutOfMemoryError をつけてテストを再実行し、ヒープダンプを取得しました。えーっと、取得したヒープダンプって何で読むのが良いんでしたっけ(←素人)

Java Mission Controlで読めたはず、と思ってググったら、今は名前が変わってJDK Mission Controlになっていたのですが(←素人)細かいことは気にせず、ダウンロードして実行して、File - Open Fileからヒープダンプのhprofファイルを読み込みました。
↓こんな感じでヒープを占めるオブジェクトの傾向が分かります。

f:id:cero-t:20200812214730p:plain
JMCでヒープダンプを開くとこういう情報が分かる

一番上にある byte[][] がヒープの7割も占めていて明らかに怪しいので、ダブルクリックして詳細を見ます。
↓こんな感じでどこから参照されているかが分かります。

f:id:cero-t:20200812214806p:plain
オブジェクトの親子関係も追跡できる

どうやら org.postgresql.core.Tuple.data から参照されているが分かり、このパッケージ名からやはりDBから読み込んだ100万レコードがヒープを埋めているであろうことがほぼ確定しました。

問題はどこで起きてるんだ!

今度はアプリケーションの方から問題を追跡します。デバッガで少し追ってみると、問題が起きている箇所がすぐに分かりました。

try (Stream<EMP> stream = dslContext.selectFrom(EMP).stream()) {
    stream.forEach(e -> {
        // 集計処理
    })
}

dslContextというのはjOOQのDslContextクラスのインスタンスです。この処理で select * from EMP が実行されて、その結果をStreamとして取得しているわけです。
ただここで // 集計処理 と書いた部分には入っておらず、forEachを呼び出した時点でOutOfMemoryErrorが発生していることが分かりました。

なんてこった、jOOQのstreamメソッドは逐次処理をするんじゃなくて全件まとめて取ってくるヤツなのかい? どんな幼稚な処理を書いたらそうなるんだい? jOOQだからってジョークじゃ済まないよ? と怒りに震えながら、ツイートをしました。

後にこれは完全にとばっちりだったことが分かったのですが、シンガプーラ使いさん(シンガプーラって何ですか?)と、jOOQの公式アカウント様からもリプライいただいてしまい、大変恐縮しております。申し訳ありませんでした。

fetchSize()が効かない、だと!?

公式アカウント様が「streamメソッドはLazyローディングだよ。場合によっては fetchSize メソッドを使うと良いよ」とおっしゃるので、まずそれを試してみました。

try (Stream<EMP> stream = dslContext.selectFrom(EMP).fetchSize(1000).stream()) {
    stream.forEach(e -> {
        // 集計処理
    })
}

しかし状況は変わりません。fetchSizeを1にしてもOOMEが発生してしまいました。

次にシンガプーラ使いさんから教えてもらった fetchLazy メソッドも試してみました。

var cursor = dslContext.selectFrom(BUDGET_REQUEST).fetchSize(1).fetchLazy();
while (cursor.hasNext()) {
    // 集計処理
}

それでも状況は変わりません。 この辺りで、問題はjOOQではなくJDBCドライバ周りなのではないかと考え始め、jOOQを外して検証することにしました。

JDBCで問題が再現しちまった!

僕もO/Rマッパーを自作するタイプの人間ですから、生JDBCで処理を書くのもお手の物です。こんなシンプルなコードを書いてみました。

try (Connection conn = dataSource.getConnection();
        PreparedStatement stmt = conn.prepareStatement("select * from EMP");
        ResultSet resultSet = stmt.executeQuery()) {
    while (resultSet.next()) {
        // 集計処理
    }
}

うんとこしょ、どっこいしょ、それでもOOMEは消えません。これでjOOQは関係なく、PostgreSQLJDBCドライバ周りの問題だろうと絞り込めました。

ドキュメント、あったよ!

先に書いたシンプルなコードですらOOMEが発生してしまう状況になってくると、私が何か勘違いしているのかも知れないな、なんて一人称まで謙虚になってきます。何かPostgreSQLでは特別なお作法があるのだろうかと思い、「postgresql jdbc lazy loading」でググってみたところ、みんな大好きStack Overflowにたどり着きました。

https://stackoverflow.com/questions/984073/java-jdbc-lazy-loaded-resultset

Another example: here's the documentation for the PostgreSQL behavior. If auto-commit is turned on, then the ResultSet will fetch all the rows at once, but if it's off, then you can use setFetchSize() as expected.

!?!?

ResultSet will fetch all the rows at once

まさに今回起きている現象そのものです。リンクされていたドキュメントを読んでみると、明確に書かれていました。

https://jdbc.postgresql.org/documentation/head/query.html#query-with-cursor

By default the driver collects all the results for the query at once.

はぁ〜!? なんでそんな実装にしとんねん!!!
問題の原因が分かった喜びよりも、この理不尽な実装に対する怒りの方が大きかったです(←理不尽な怒り)

これで解決だな

ドキュメントから、関係ありそうな部分を抜粋しますと。

Cursor based ResultSets cannot be used in all situations. There a number of restrictions which will make the driver silently fall back to fetching the whole ResultSet at once.

  • The Connection must not be in autocommit mode. The backend closes cursors at the end of transactions, so in autocommit mode the backend will have closed the cursor before anything can be fetched from it.

どうやらautoCommitがtrueになっている場合は、カーソルが使えないようです。そんなわけで Connection#setAutoCommit(false) したところ、、、jOOQの fetchSize() メソッドが効くようになって、OOMEが発生しなくなりました!

そもそもなぜautoCommitがtrueになっていたかと言うと、

  • バッチ本体では setAutoCommit(false) してから処理していたが、テストではロジックの中心部分だけ直接呼び出していた
  • テストでは面倒だったのでautoCommitをデフォルト値(true)のままにしていた

という、非常に運の悪い状況になっていました。 いやだって、autoCommitのtrue/falseでそんなに挙動が変わるなんて想像もしてなかったんだもん・・・。

さらに、Spring Boot + jOOQ + PostgreSQLで書いていたWebアプリケーションにおいてもautoCommitがtrueのままになっていました。トランザクションが効いている限りはautoCommitがtrueのままになることはあり得ないのですが、実はSpring Boot + jOOQの組み合わせでは、たとえ spring-boot-starter-jooq を使っていても、そのままでは @Transactional アノテーションが効かない状態になっているのでした。

https://www.baeldung.com/spring-boot-support-for-jooq

いやまさか、Spring Bootとの連携が公式に謳われているようなライブラリで、@Transcational が効かないだなんて想像もしてなかったんだもん・・・。

まとめるぞ!

そんなわけで、今回のまとめです。

  • PostgreSQLはfetchSizeを指定しないと、ResultSetに検索結果が全て入る
  • PostgreSQLはautoCommitがtrueだと、fetchSizeを指定しても効果がない
  • そもそもサボってautoCommitをtrueのままにしてたのが、すべてのきっかけだったわけじゃん
  • でもそのおかげでSpring BootとjOOQのトランザクションサポートの課題も見つかって良かったね!

という感じで、原因の追及と対応に丸一日かかりましたが、良い経験になりました。

メッシュルーターの選び方について整理した。

急に冷え込んだ昨今、さすがにこの寒さではメッシュの服など着ることができませんので、せめてルーターだけでもメッシュにしてはどうでしょうか。
なーんて、寒さに拍車を掛けかねない妖怪、@cero_t です。みなさまお風邪など召されておりませんでしょうか。

さて、今年のはじめ頃に、Linksys Velopというメッシュルーターを買いました。 cero-t.hatenadiary.jp

メッシュルーターというのは、複数のルーターで同じSSIDを使い、家中でどこにいても快適にWi-Fiが使えるというものです。既存のルーターを複数使って、ただただ同じSSIDを使うだけだと、電波の悪いルーターに繋ぎっぱなしになることがありますが、メッシュルーターであれば端末さえ対応していれば(大体対応してる)通信状況の良いSSIDが選択されます。

そんなわけで実際にメッシュルーターを使って色々試し、なるほどこれは便利だなという部分と、なんとこれは知らなかったなみたいな部分があり、様々な経験値を貯めていたところ、ちょうど実家のほうからも「Wi-Fiが不安定だから何とかしたい」という声が届きまして、このタイミングでメッシュルーターの選び方や構成について改めて整理することにしました。

製品選び

この1年で、だいぶメッシュルーター製品が増えてきています。GoogleからもGoogle Wifiに続きGoogle Nest Wifiという よく分からない 製品が出てきましたし、2019年末の現在は、Wi-Fi 6(802.11ax)対応がちょうど出てくるタイミングでもあります。
ただWi-Fi 6対応製品はまだまだ高価なのと、自宅にも実家にもWi-Fi 6対応デバイスがないので、今回はWi-Fi 6対応製品のことは考えないことにしました。

そうやって選択肢が増えてくると、どの製品を選んで良いか分からなくなりがちですので、まずは選び方について整理します。 既製品リストは、こちらのサイトが詳しいです。 24wireless.info

製品を選ぶ時に気をつけるポイントは、まず2つ、「有線LANの有無」と「契約している回線(のルーター)」です。

(Q1) 各部屋に有線LANが配線されているか?

1つめの問は、各部屋に有線LANが配線してあり、メッシュルーター間を有線でつなぐことができるかどうかです。

  • できる → 「有線バックホール」に対応した「デュアルバンド」製品を選ぶ
  • できない → 「トラインド」製品を選ぶ

有線LANを使ったメッシュルーター間の通信は「有線バックホール」または「イーサネットバックホール」と呼ばれています。有線LANが配線されている家であれば、この機能を使ったほうが通信の速度も品質も高くなります。ちなみに無線を使った通信は「無線バックホール」「Wi-Fiバックホール」と呼ばれています。

また、有線バックホールを使う場合に、基本的には「トライバンド」対応製品を選ぶ必要はなく、「デュアルバンド」対応製品を選べば良いようです。トライバンドのうち1バンドはメッシュルーター間の通信に使わるようで(そうでない製品もあるかも知れませんが)、割高なトライバンド製品を買っても性能がコストに見合わなくなるためです。
逆に有線LANが使えない場合には、トライバンド製品を選んだほうが無難でしょうね。

(Q2) インターネット回線はどれか?

2つめの問は、インターネット回線の接続方式についてです。接続方式とルーター機能の有無によって選ぶべき製品が変わります。

  1. フレッツ光eo光など、IPv4のPPPoE接続
  2. フレッツ光プラスなど、IPv6のIPoE接続
  3. auひかりやNURO光など、ホームゲートウェイルーター機能をOFFにできないタイプ

これによって、次のように選ぶ製品が変わります

  • 1 → どれを選んでも良い。高機能/高性能なルーターを選ぶとルーターの機能を活かせる
  • 2 → 「フレッツ網でのIPv6 IPoE接続」に対応した製品を選ぶ(Buffalo、ELECOM、Synologyのいずれか)
  • 3 → 「ブリッジモードでのメッシュNW構築」に対応した製品を選ぶ。ルーター自体の性能は活かしにくい

インターネットガチ勢の皆様におかれましては、フレッツ光を使っておきながらIPv4に甘んじることはまず考えられないと思いますので、フレッツ光においては選択肢の「1」は消えて「2」になりますので、Buffalo、ELECOM、Synologyの3社のうちのどれかを選ぶ形になります。

それ以外、たとえばeo光auひかり、NURO光などの場合は、どれを選んでも構わないことになります。
eo光はホームゲートウェイルーター機能をOFFにできますので、高機能/高性能なメッシュルーターを使うと良いでしょう。
一方、auひかりやNURO光なら安めのやつで良いかなという感覚です。

逆に言えば、メッシュルーターが持つQoS設定やアクセス制御、セキュリティ機能などを使いたい場合であれば、ISPが提供するホームゲートウェイルーター機能はOFFにする必要があります。ただ、その場合に 3 のようなISPを使っているとルーター機能はOFFにできない(あるいは二重ルーターにせざるを得ない)ので、ISPごと乗り換えてしまいましょう、みたいな話になるので注意してくださいね。

ちなみに僕はISPごと乗り換えることにしました。

接続構成

続いてメッシュルーターの台数を考えたいところですが、そもそもメッシュルーターをどのように構成するかによって、必要な台数は変わってきます。
先のQ1、Q2の結果によって、構成は次の3パターンに分けることができます。

f:id:cero-t:20191202204847p:plain
メッシュの接続構成。妖怪ザツナテガキのせいでこんな絵に・・・

すみません本当は綺麗な絵を描いていたはずなのですが、どこからともなく現れた妖怪ザツナテガキに襲われてしまって、絵がこんな悲惨なことになりました。。。ちくしょう、妖怪ザツナテガキめ。。。

パターン1 : 無線接続(Q1が「できない」、Q2は何でも良い)

無線で接続する場合、インターネット回線を家に引き込んでいる箇所にメッシュルーターを1台設置します。そして、中継機としてのメッシュルーターを1台ないし2台置いて、家の中にネットワークを構築します。
一般的な大きさのマンションなら合計2台、一般的な大きさの戸建てなら合計3台ぐらいが目安だと思います(一般とは?)

ちなみにホームゲートウェイルーター機能をONにする場合は、メッシュルーター側はブリッジモードにします。ホームゲートウェイルーター機能をOFFにする場合は、メッシュルーター側をルーターモードにします。いずれにせよ接続の構成は変わりません。

パターン2 : 有線接続 ルーターモード(Q1が「できる」、Q2は「1か2」)

有線で接続し、メッシュルータールーターモードで使う場合は、インターネット回線を家に引き込んでいる箇所にメッシュルーターを1台設置します。そして、HUBを経由して電波が届きにくい部屋にメッシュルーターを1台ないし2台設置します。
やはりこれでも一般的な大きさのマンションなら合計2台、一般的な大きさの戸建てなら合計3台ぐらいが目安だと思います。

パターン3 : 有線接続 ブリッジモード(Q1が「できる」、Q2は「3」)

有線で接続し、メッシュルーターをブリッジモードで使う場合は、インターネット回線を家に引き込んでいる箇所にメッシュルーターを設置する必要はなく、よく使う部屋だけ設置するか、家全体をうまくカバーできることを想定して2台ほど設置します。もちろん、インターネット回線を引き込んでいる場所をよく使うのであれば、そこに1台目のメッシュルーターを置いても構いません(HUB経由での接続)

この場合、わりと2台でもカバーできることが多いため、2台で様子を見てみて、どこか局所的に弱い箇所があれば3台目を追加する形が良いんじゃないかと思います。

コスパ高めな製品

最後に、僕が実際に買ったり、買おうと思っていた製品を紹介しておきます。僕はコスパ厨なので、コスパの良い製品のリストになります。

TP-Link Deco M5 V2 / Deco M4

とにかく安い。デュアルバンドとは言え、3台で2万円前後という価格なのは、この製品ぐらいじゃないですかね。
有線LANが配線してある家であれば、この製品が最有力候補になります。僕の実家にはM5を入れています。

NETGEAR Orbi Micro

とにかく安い、その2。トライバンド3台で3.5万円を切ってるし、何だったら先日セールで3万円を切っているのも見ました。
無線LANで使う時の有力候補。セールの時に買おうかと迷ってたら、売り切れちゃいました。てへぺろ

Synology MR2200ac

少しお高い。ただ、IPv6対応しているので、フレッツ光IPv6で使うならこれかなと思っているやつです。NASで著名なメーカーだけに、NAS機能も充実してて面白いです。

また、親となるルーターを Synology RT2600ac に変えて、ルーター機能を強化することもできます。

この辺の、用途に合わせてルーターの強弱をつけられるのは面白いですよね。

Linksys Velop

最初に買ったメッシュルーターです。モノは良いのですが、我が家は上で言うところの「パターン3」なので、ちょっと宝の持ち腐れとなってしまいました。
デュアルバンド3台にしたほうがコスパ良かったかなという感じです。

まとめにかえて

メッシュルーターは凄く快適に使えますし、値段も2万円前後まで下がってきたおかげで、かなり試しやすくなりました。
比較的新しいタイプの製品なので、製品のライフサイクルも早めだったりしますが、であれば最初から高い製品を買っちゃうのではなく、安めの製品で使い慣れてみて、折を見て上位の製品に買い換えるのもアリかと思います。良いなと思ったら、ぜひ試してみてください。

はぁ、それはそれとして、絵心って欲しいですよね。

それでは!

Dapr + JavaでHello worldしました。

先日、MicrosoftがDaprというプロダクトをOSSで公開しました。

www.publickey1.jp

Distributed Application Runtimeの略だそうで、なんかIstio的な感じなのかなーと思ったのですが「ステート管理」みたいな機能もある所が少し気になって、ドキュメントとかを眺めていると、ステート管理、メッセージング、アクターなど、ただのサイドカーよりも機能が多めになっていて、かつ、分散トレーシングの機能も持っている辺りを見て、あぁなるほどとなりました。ステート管理やメッセージングをプラットフォーム側が持つようになれば、AOPやBCIなしで分散トレーシングができるようになるし、これはアリだなという謎の納得感を得ました。

まぁ細かいことはさておき、Daprのアプローチがちょっと面白いなと思い、Daprそのものというよりも、このようなアプローチがゲームチェンジャーになるのかなと思うところがあったので、少し動かして確認してみようという気持ちになりました。
なんというか、こういう少し未来を先取りしたようなプロダクトが出てくると、良いなってなりますよね。「明日が好きな人だけが、地球を回す」という言葉がありましたが、地球を回しにいきたいと思います。ちょっと意味不明ですね。

そんなわけで、まずはHello worldまでやりました。

Daprのインストール

まず、DaprのCLIをインストールします。先にDockerをインストールしておく必要がありますが、このブログの読者で自分のPCにDockerが入ってない人とかいないですよね? さすがに?

Dockerさえ入っていれば、Macではこれを実行するだけです。

curl -fsSL https://raw.githubusercontent.com/dapr/cli/master/install/install.sh | /bin/bash

他のOSのインストール方法などは、ドキュメントを参照してください。 https://github.com/dapr/docs/blob/master/getting-started/environment-setup.md

このインストールが終わった時点で dapr --version とかをしても、まだエラーになります。先に初期化をする必要があります。

dapr init

これでDapr側は準備完了です。おもむろに dapr --version とかしても大丈夫です。

Micronautのインストール

Dapr上で動くサービスは、HTTPかgRPCで通信を受け取る必要があります。残念ながらJavaでは標準APIだけでHTTPサービスを作るのが面倒くさい(Socketサーバか、com.sunパッケージのHttpServerしかない)ので、Spring BootやMicronautなどを使うことになります。

今回はMicronautを使うことにしました。既に皆さんMicronautもインストール済みだとは思いますが、もし mn --version して command not found になった人は、心から反省して、Micronautのドキュメントを見てCLIをインストールしてください。 https://docs.micronaut.io/latest/guide/index.html#buildCLI

僕も反省しながら次のコマンドを打ちました。

brew update
brew install micronaut

これでMicronautも準備できました。

MicronautでHello worldアプリを作る

micronautでHello worldするWebアプリを作ります。

mn create-app hello-world

これで出来上がった hello-worldsrc/main/java/hello/world フォルダにコントローラークラスを作ります。ソースはほぼ公式ドキュメントからのコピペです。

package hello.world;

import io.micronaut.http.MediaType;
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Get;

@Controller("/hello") 
public class HelloController {

    @Get(produces = MediaType.TEXT_PLAIN) 
    public String index() {
        return "Hello, Sofmap World"; 
    }
}

あとは hello-world フォルダで ./gradlew run すれば、Webサーバが立ち上がります。
curl localhost:8080/hello を実行して Hello, Sofmap World とメッセージが出れば完成です。

Dapr上でMicronautを実行

それでは、いま作ったMicronautアプリを、Dapr上で走らせます。コマンドは次のようになります。

dapr run --app-id hello-sofmap --app-port 8080 --port 8000 ./gradlew run

--app-port オプションは中で動作するMicronautが使うポート、--portオプションはDaprの外から呼び出す時のポートになります。そのオプションの後ろに実行コマンドを付ければ、そのコマンドがDapr上で実行されるわけです。とても簡単ですね。

上のコマンドを実行してDaprが起動したら、curlコマンドでDaprのエンドポイントを叩いて処理を実行します。

curl localhost:8000/v1.0/invoke/hello-sofmap/method/hello

これで無事 Hello, Sofmap World が表示されました!

まとめ

総じて、何らハマることなく、DaprのHello worldができました。
先ほど、11月の関ジャバでDaprについて話すことになったので、しばらく、他のステートやアクター、分散トレーシングなども触ってみたいと思います。

それでは、
行こうよ、まぶしい光の世界!

NEW ALIENWARE m15レポート。格ゲー性能は十分 #デルアンバサダー

DELLアンバサダープログラムのNEW ALIENWARE m15(以降、ALIENWARE)レポート第二弾、今回はゲーミングの性能です。 かの平清盛も「ゲームができずんばゲーミングノートにあらず」などと言ったことがよく知られていますね(※言ってない)

ということで、ALIENWAREのゲーミング性能について検証したいと思います。今回も、過去のレポートでも利用していた「Street Fighgter V: Arcade Edition(以降、ストV)」と「FIGHTING EX LAYER(以降、FEXL)」の2本を使い、高画質でも60fpsで安定するかどうかを検証します。
対戦格闘ゲームですから60fpsで動くことは必須であり、あとはどこまで画質を上げられるかの勝負となるわけです。

なお今回利用するALIENEWAREは、Core i7-9750HとGeForce RTX 2070 with MAX-Qを積んでいる、ハイエンドの一歩手前くらいの性能のゲーミングノートです。

ストVを試してみる

ストVを最高画質のフルHD(1920 x 1080)で動かしてみた動画がこちらです。左上に小さいのですがfpsが表示されていて、これが60fpsで安定するかどうかを確認します。

www.youtube.com

読み込み中やキャラクターセレクト画面では少しfpsが落ちますが、これは何の問題もありません。対戦開始後、スーパーコンボを出したあたりのfpsに注目すると、特に問題なく60fpsで安定していることが分かりました。
XPS 15 (GeForce GTX 1050)の時は57fpsくらい、XPS 15 2-in-1 (Core i7-8705G) では50fpsくらいまで下がってしまったことを考えると、さすがはRXT 2070という印象です。

続いて、せっかくの4Kディスプレイを活かすべく、最高画質のまま4K (3840 x 2160) でも動かしてみます。結果は、次の動画のようになりました。

www.youtube.com

さすがにこのスペックでも4Kでのプレイは辛いようで、対戦直後から50fpsぐらいまで下がり、スーパーコンボを出すと40fpsくらいまで下がってしまいました。
4Kでも画質を落とせば動くようになるかも知れませんが、画質を落とすくらいならむしろ解像度を落とした方が良いでしょうから、他の画質では試しませんでした。

FEXLも試してみる

続いて、FIGHTING EX LAYERでも試してみます。まずは最高画質、フルHD (1920 x 1080) です。

www.youtube.com

キャラクター選択、対戦、スーパーコンボ、フィニッシュとも、60fpsで安定しています。たまに61fps、59fpsとなりますが、測定誤差の範囲でしょう。期待していた通り、全く問題ありません。
XPS 2-in-1 では、対戦中に58fpsくらい、フィニッシュ時に48fpsくらいまで低下していましたから、やはり明らかな差があります。

さて、FEXLも4Kにすることができるので、最高画質のまま4K (3840 x 2160) で動かしてみます。

www.youtube.com

これはさすがに厳しくて、設定画面の時点でもう31〜34fpsくらいまで下がってしまいました。これでは対戦中に60fps稼働することが全く期待できないため、ここで止めることとしました。やはり最高画質4Kは、このスペックでは厳しいことが分かりました。
格ゲーを4K最高解像度で楽しむためには、RTX 2080を試すしかないんですかね? 機会があれば試してみたいですね?

液晶の遅延は?

さて、続いては気になる液晶の遅延や残像について調べたいと思います。

HORIのポータブルゲーミングモニターをHDMI接続して、セカンダリディスプレイ(複製表示)とします。そしてLCD Display Checkerの出力を両方の画面に映し、それをスロー撮影して遅延の状況を確認します。スロー撮影にはGoogle Pixel 3 XLの480fps撮影を利用しました。

www.youtube.com

コマ送りすると、おおむね0〜2コマ分ほどALIENWAREの出力が先行していることが分かります。480fpsの2コマ分だとすると1/240秒、つまり最大で0.25F(4.2ms)ほどALIENWAREの液晶の方が表示が早いことになります。
過去にXPS 15やXPS 15 2-in-1と比較した時には、HORIのモニターの方が0.25〜0.5Fほど表示が早かったことと比べると、結果が逆転しています。さすがはゲーミングノートの液晶というところでしょうか。
また、残像の残り方もHORIのモニターよりも少なく、いずれにせよゲーミング用として申し分ないモニターだと思います。

G-SYNCは対応していない

最後に、G-SYNCについてです。
結論から言うと、残念ながらALIENWAREのディスプレイはG-SYNCに対応していません。カタログに記載していないだけで、こっそり対応されたりしてないかな・・・と思って試してみたのですが、ゲーム側の設定で垂直同期をOFFにしてキャラを動かすと、普通にティアリングが発生してしまいました。ここだけは少し残念ですね。

まとめ

そんなわけで、2回に分けてNEW ALIENWARE m15のレポートをしてきました。

ゲームをするのに申し分ない性能で、有機ELの液晶がかなり綺麗で、キーボードも良好、ポート類なども全部ある、という辺りが好感触でした。唯一の欠点は、ディスプレイがG-SYNCに非対応なところでしょうかね。
また、重さも2.1kg程度なので、日常的に持ち歩けるかは判断が分かれるかも知れませんが、ゲーム機を持ち寄る対戦会のようなイベントに持っていく分には、何の抵抗もないという感じです。

f:id:cero-t:20191029113957j:plain
都内某所で行われているFEXL対戦会。ガチ勢だ!

ゲームに使うだけでなく、4K有機ELのおかげで動画鑑賞としても良いですし、癖のないNキーロールオーバー対応キーボードのおかげで、仕事や書き物にも使えるなという印象でした。
僕はいまMacをメインで使っていますが、もしメインをWindowsに切り替えるなら、性能面とキーボードの良さという理由で、ゲーミングノートにしたいと思っています。ALIENWAREはその選択肢の一つとして、決してアリエンワーではなく、候補の一つになるなと思いました。

f:id:cero-t:20191029113411p:plain
アリエンワーでググってみました。

はい、そんなわけで、
DELLさん、試用機のご提供、ありがとうございました!