std::unorderd_mapになんでも入れてみた。

とりあえずコード。

 

class Session
{
private:
    std::unordered_map<std::string, std::shared_ptr<void>> values;

public:
    template <typename T>
    bool getValue(const std::string &name, T *value)
    {
        std::shared_ptr<void> data = values[name];
        if (data != nullptr) {
            void* raw = data.get();
            *value = *((T*) raw);
            return true;
        }
        return false;
    }

    template <typename T>
    void setValue(const std::string &name, T *value)
    {
        values.emplace(std::make_pair(name, std::make_shared<T>(*value)));
    }
};

struct STest
{
    int m1;
    std::string m2;
};

int main()
{
    STest t1{2, "hoge"};
    Session s;
    s.setValue<STest>("key", &t1);

    STest t2;
    if (s.getValue<STest>("key", &t2)) {
        std::cout << "m1:" << t2.m1 << ", m2:" << t2.m2 << std::endl; // 2, hoge
    }
}

 

となる。

コンテナから引き出す時に、無駄に1回生成が走るから、

大きいインスタンスでは注意が必要。

 

で、なぜこれをつくるかというと、

例えばTCPの常時接続の際、

セッションで引き回せると、

簡単に値を保持できるという狙いのため。

 

とはいえ、ポインタのキャスト多いから、大丈夫かはわからん。。

確実な使い方しないと危なそう。。

 

以上

投稿日時:2018年04月09日 22:49   カテゴリー:c/c++  

mysqlサーバが突然死して、

クライアント側から見ると生きている状態、つまりハーフCLOSE状態となるのだが、

このとき、他のmysqlサーバに接続している状態で、上記が発生すると、

生きている側のmysqlサーバへの接続がCLOSEされない待ち状態となることがある。

HTTPアクセスからだと、以下のような場合が該当する。

  1. mysqlサーバAにconnect
  2. mysqlサーバBにconnect
  3. mysqlサーバAにbegin
  4. mysqlサーバBにbegin
  5. mysqlサーバAにselect for update
  6. mysqlサーバBにselect
  7. mysqlサーバBが突然死
  8. HTTP要求がタイムアウト

このとき、6の応答を待ったまま、処理が続行され、

5のロックが解除されない状態となる。

5のロックを解除するには、

  • mysqlサーバAからプロセスをkillする
  • HTTPサーバを再起動する
  • 実行タイムアウトまで待つ

という方法のいずれかになる。

JDBCではsocketTimeoutといういわゆる実行タイムアウトがあるのだが、

phpのPDOでは、デフォルトで実行タイムアウトの概念はない。

set session 〜 で対応するくらいになるだろう。

しかし、set session 〜 で出来ることは、mysqlサーバのクエリー実行時間の制御であり、

クライアント側のタイムアウト制御はできない。

そこで、あのmysqlndを使っているのであれば、

mysqlnd.net_read_timeout

というパラメータを設定することで、実行タイムアウト例外を検知できるようになる。

apacheであれば、virtualhostに、php-fpmであれば、www.confに設定できる。

 

このように実行タイムアウト、いわゆるexecution timeoutをちゃんと処理していないことで、

痛い目を見る可能性があるので、このあたりはチェックしておくといざというときに大きな障害を回避できる。

 

以上

投稿日時:2018年03月15日 23:33   カテゴリー:mysql, php  

fedora27にて、

  • java-1.8.0-openjdk-1.8.0.161-5.b14.fc27.x86_64
  • openjfx-8.0.152-12.b04.fc27.x86_64

でjavafxを動かそうと思ったら、全く動かなかった。

そこで、

  • jdk1.8-1.8.0_161-fcs.x86_64

いわゆるOracleJDKに変更したら、無事動いた。

javafx以外は問題なさそうなんだけど。。。

ちなみにOracleJDKでも、TextFieldに日本語入力を行おうとすると、

ざっくり以下のようなSIGSGVが起きる。。


# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x00007f1128822e11, pid=9155, tid=0x00007f10f8126700
#
# JRE version: Java(TM) SE Runtime Environment (8.0_161-b12) (build 1.8.0_161-b12)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.161-b12 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# j com.sun.glass.ui.gtk.GtkView.notifyInputMethodDraw(Ljava/lang/String;III[B)V+16

 

javafxがんばれ!

 

以上

投稿日時:2018年03月15日 23:12   カテゴリー:fedora, java  

fedora27 workstationをUSBメモリにインストールした。

使用したUSBメモリは、 SanDisk Extreme 500 Portable SSD というポータブルUSBで、

こいつがかなり素晴らしい。速い。

※正確にはポータブルSSDなんですが。。

 

以前、USBメモリに仮想マシンを入れた時は、

遅くて使い物にならなかったが、今回はそのようなことはなく、

clionがバリバリ使える。快適。ブラウザも快適。

ちなみにUSB3ポートに挿して使ってます。

 

fedora27については、最初にmozcを入れて日本語入力の快適化を図ろうと思ったが、

mozcはもう推奨されないみたいだし、デフォルトで直接入力になるし、

元から入っているのlibkkcで充分だった。これだとデフォルトでかな入力になるしね。でも変換イマイチ。。

そのほか、vscodeも動くし、jetbrainのIDEも問題なさそうだし、

LINUXプログラミングがはかどることでしょう。

 

以上

投稿日時:2018年03月15日 23:02   カテゴリー:fedora  

javaでfluentdのサーバ、

つまりforwordを受ける側の処理なのだが、

これを書こうと思い、

fluentdのmsgpackのフォーマットを調査していたところ、

以下のライブラリに出会った。

https://github.com/okumin/influent

 

上記のライブラリはとても素晴らしく、

javaのマルチスレッド、NIOを十二部に活用されていた。

テストをしたところ、十分な負荷にも耐えられ、

高い安定性を誇ることが分かった。

※テストしたのは、バージョン0.3.0

 

ただ、msgpackを前提としているので、

jsonデータのmsgpack化ではパースエラーになる。

具体的には、公式に提供されているphpライブラリだと、

デフォルトの書き込みフォーマットはjsonであるため、

ここはmsgpackに変更する必要がある。

 

とはいえ、とても優れたプロダクトであり、

UDPのハートビートにも対応されている点は、

とても利用しやすいと感じた。感謝感謝。

 

以上

投稿日時:2018年01月20日 22:27   カテゴリー:java  

クラウド上のインスタンスにおいて、

Redisのpub/subをしている際、

もし、そのRedisインスタンスがいきなり落ちて、いきなり稼働した結果、

subscribe側が正常にTCP切断を出来ない、

つまりsubscribe側から見れば、まるでRedisへの接続が生きているかのような状態に陥り、

自動的な再接続が機能しないという事態に陥った。。。

 

これは、Redisのsubscribeにはタイムアウトがないという点と、

subscribeが受動的なものであるという特性であるが故に、

発生した問題である。

 

クラウドでは、インスタンスの瞬間的なダウン&アップがたまにあるので、

データベースの自動起動を有効にするかを検討する必要がある。

それはmonitなどによる自動再起動も然りである。

まあ、DISKに書き込むタイプの処理を使っておけば、

このような問題に対して、比較的軽微なダメージで済むかもしれない(もしくはノーダメージ)ので、

その点も留意して、利用プロダクトの選定、プログラムの対応を検討する必要があると思ったわけです。

 

以上

投稿日時:2017年08月30日 23:12   カテゴリー:redis  

10.1から10.2で変更になるパラメータを見てみた。

個人的に気になるものは以下の通り。

・max_allowed_packet
4MB -> 16MB

・sql_mode
NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION -> STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

・innodb_additional_mem_pool_size
removed

・innodb_autoinc_lock_mode
1 -> 2

・innodb_buffer_pool_dump_at_shutdown
off -> on

・innodb_buffer_pool_dump_pct
100 -> 25

・innodb_buffer_pool_load_at_startup
off -> on

・innodb_buffer_pool_size
Dynamic

・innodb_checksum_algorithm
innodb -> crc32

・innodb_compression_algorithm
none -> zlib

・innodb_file_format
Deprecated

・innodb_file_format_max
Deprecated

・innodb_flush_sync
new

・innodb_large_prefix
Deprecated

 

俯瞰してみると、これまで10.1では必ず設定していたパラメータが、

defaultで採用されているケースが多い。

そして、767byteを超えるインデックスについて扱っていた

large_prefixに関係するパラメータがdeprecatedになり、

defaultで3072byteまでインデックスサイズが拡張されるということか。。

 

もうちょい深読みしてみないと、上記の変更が生む弊害が読めないが、

往々にして、より扱いやすい方向に進んでいる気がする。

なお、上記のパラメータの多くはMySQL5.7でも採用されている。

 

以上

投稿日時:2017年08月30日 22:33   カテゴリー:mariadb, mysql  

mysqlではインデックスは1つしか使えないと言われていたが、

実際はインデックスマージという機能があるため、

2つ同時に使うことは可能である。

 

ただ、インデックスマージはwhere句でのみ作用可能に思われるので、

whereとorder byで違うインデックスを使うのは無理なのではないかと思っている。

MySQL5.7でもMariaDB10.2でも、このあたりの記述が見当たらなかった。。

 

上記の理解であっているのか、非常に気になるところである。

進展があったら、書こうと思う。

 

以上

投稿日時:2017年07月23日 00:03   カテゴリー:mariadb, mysql  

fluentdとelasticsearchを長時間つないでいると、

「Cannot get new connection from pool.」というエラーが出る。

これが出ると、fluentdを再起動しなければならなかった。

そのため、logrotateでfluentdを再起動して、この問題を回避していた。

この現象が出るfluentdのプラグインのバージョンは以下の通りであった。

(たぶん、これより古いバージョンでも出てたのでは)

  • elasticsearch : 1.1.pre
  • elasticsearch-api : 1.1.pre
  • elasticsearch-transport : 1.1.pre
  • fluent-plugin-elasticsearch : 1.9.2

 

上記を以下のバージョンに変更したところ、コネクションエラーは一切起きなくなった。

  • elasticsearch : 5.0.4
  • elasticsearch-api : 5.0.4
  • elasticsearch-transport : 5.0.4
  • fluent-plugin-elasticsearch : 1.9.5

 

念のためresurrect_afterという設定も入れてはいる。

 

一応、これで1か月以上再起動かけなくても、エラーは出なくなった。

ちなみに、elastic search本体のバージョンは5系である。

 

以上

投稿日時:2017年07月22日 23:48   カテゴリー:elasticsearch, server  

GaleraClusterでは、書き込みノードを1つに絞って、

デッドロックを回避したほうがいいとよく言われる。

maxscaleを使えば、書き込みノードを絞ることは簡単であるが、

単に3つのクエリーを実行するだけで、書き込みノードを絞れるので、記載しておく。

なお、Perconaも似たような方法をやっていた。

 


1.SHOW GLOBAL STATUS LIKE 'wsrep_local_state'; の結果が4である

2.SHOW VARIABLES LIKE 'read_only'; の結果がoffである

3.SHOW GLOBAL STATUS LIKE 'wsrep_local_index'; の結果が0である

 

以上、3つを満たした場合、書き込みノードとして判定してOK。

haproxyと組み合わせることも簡単なので、

どこかでhaproxyとの組み合わせについても記載しようと思う。

 

以上

投稿日時:2017年07月22日 23:33   カテゴリー:mariadb, mysql