构建用于日志的Elasticsearch集群

想要体验kibana4-BETA2和elasticsearch-1.4,我在aws上搭建了一个常见的配置,并记录了一些注意事项。
首先是安装和部分配置,环境是ubuntu 12.04。

选择实例

    • elasticsearchはHEAPにメモリの50%以下割当推奨

 

    • kibana4になってからaggregationを使ったリクエストになっているのでcpuよりメモリの制約のほうが大きそう

 

    application logを流す予定で実測80Mbpsくらいしか出ないネットワークパフォーマンス中のインスタンスはきつそう

因此,我们决定采用多个m3.xlarge实例进行观察和排列。

硬盘周围

    • EBS上に構築。diskioを考えるとそれなりに大きくしたほうが良さそう

 

    あとでdisk を非停止で追加したい(この時点ではdisk性能とか容量が問題になるかもしれないと考えていたので)

在LVM下绑定一个1G的EBS。

顺便提一下,大约在kernel 3.2.54附近存在无法扩展XFS的bug,所以如果使用XFS的话,可能需要稍微关注一下kernel的版本。

> sudo apt-get install lvm2
> sudo pvcreate /dev/xvdf
> sudo vgcreate vg1 /dev/xvdf
> sudo lvcreate -L 999.99G -n lv1 vg1
> sudo apt-get install xfsprogs
> sudo mkfs.xfs /dev/vg1/lv1
> sudo mount -o "discard,noatime,nodiratime,nobarrier" /dev/vg1/lv1 /mnt
> sudo sh -c "echo '/dev/mapper/vg1-lv1 /mnt xfs discard,noatime,nodiratime,nobarrier 0 0' >> /etc/fstab"

安装Elasticsearch

    • java7が必須

 

    • あとはdebで1.4をインストール sudo dpkg -i elasticsearch-1.4.0.deb

定番のpluginをいくつか

sudo /usr/share/elasticsearch/bin/plugin –install lukas-vlcek/bigdesk
sudo /usr/share/elasticsearch/bin/plugin –install mobz/elasticsearch-head
sudo /usr/share/elasticsearch/bin/plugin –install elasticsearch/elasticsearch-analysis-kuromoji/2.4.1
sudo /usr/share/elasticsearch/bin/plugin –install river-csv -url https://github.com/AgileWorksOrg/elasticsearch-river-csv/releases/download/2.1.1/elasticsearch-river-csv-2.1.1.zip

对config进行修改

/etc/elasticsearch/elasticsearch.yml文件的修改位置是。

    • cluster.name

なんか名前つけておくとよろし

node.name

awsならホスト名とかで問題なし

index.number_of_shards

一つのインデックスのシャードの数のデフォルト値。
一度作ったインデックスは変更できないので今回は10に
logstash形式のインデックスにするなら翌日分から変更は可能

index.number_of_replicas

最初0にしていたけど、問題が発生して後1に。
0のままだとインスタンスを退役させるときにshardを非停止で移動する方法が見つからなかった…
_cluster/reroute の moveは移動後、リバランシングが走って他のshardが戻ってきてしまった

path.data
discovery.zen.ping.multicast.enabled: false

指定してないclusterに勝手にjoinするのはあまり好みではなかったため…

discovery.zen.ping.unicast.hosts: [“xxx.xxx.xxx.xx”]

elasticsearch間の通信は9300

init.dの修正

debでいれると、ES_HEAP_SIZEがべた書きしてあるので、そこを/etc/defaultから読むとか直接書き換えるとか好きに修正
利用可能なメモリ量の50%以下で31GB以下らしい

如果这样启动的话,会自动开始通信。

安全组

    • 9200と9300が疎通できればOK

 

    • 9300はnode間の通信で、9200は外からAPIやweb plugin表示するときに使う。

 

    9200はELBの下にぶら下げることにした

流畅的日志收集器

    • logstash形式でlogをelasticsearchに

 

    既存のログの構造を変えられないとかよくある制約のおかげで、アプリケーション内でobject dumpした物をfluentdのpluginでparseして構造化

如果不加思索地以这种方式对日志进行流式处理,由于对象的结构非常深,导致建立索引的成本很高,很快 Elasticsearch 就会堵塞起来。
因此,将只需要的元素设为建立索引的目标,并根据需要逐步增加建立索引的目标…

模板(Elasticsearch的功能)

    • データをインサートするタイミングで適応するインデックスのマッピングを設定する機能

インデックスが期間で切り替わるlogstash形式と非常に相性が良さそうだった

インサートするインデックスの名前が正規表現で書けるtemplate判別文字列と一致したらそのtemplateが適応される

logstash-*とかにしておくと、logstash-2014.12.19のようなlogstash形式のインデックスとマッチする

{
  "template" : "logstash-*", # ここにマッチしたら適応される
  "order" : 10, # orderは正規表現の適応優先順位
  "settings" : {
    "index" : {
      "number_of_replicas" : 1 # あとで変更したくなったらここにも書いておくことも可能
    }
  },
  "mappings" : {
    "production_log" : { # 自分で設定したtype名
      "properties" : {
        "@timestamp" : { # fluent-plugin-elasticsearchのdefalutだと時刻はこの形
          "type" : "date",
          "format" : "dateOptionalTime"
        },
        ### --- ここから先はそれぞれの構造 --- ###
        ### とりあえずよくありそうな形で埋めておく
        "ua" : {
          "type" : "string"
          "index" : "not_analyzed"
          # 検索ではなくkibanaを使ったVisuarizationが主目的の場合はnot_analyzedのほうが無難
          # term aggragationを使ったりしたら分かち書きしたものごとに重複して描画されたりする
        },
        "result" : {
          "type" : "integer"
        },
        "path" : {
          "type" : "string",
          "index" : "not_analyzed"
        },
        "params" : {
          "dynamic": false, #これでここより下の階層は一致する要素だけインデックスできる模様
          "properties" : {
            "user_id" : {
              "type" : "integer"
            },
            "firneds" : {
              "dynamic": false, # さらに深い階層も面倒だけどこんな感じで...
              "properties" : {
                "count" : {
                  "type" : "integer"
                }
              }
            },
            "map" : {
              # 緯度経度を格納するgeo_pointというインデックスタイプもある
              # kibana4からgeo_pointインデックスは地図上にマッピングすることも可能
              # valueは{ "lat" : "35.7056396", "lon" : "139.7518913"} の決まった形でいれる必要がある
              # ここ気づくのに時間がかかった...
              "type" : "geo_point",
              "geohash" : true,
              "geohash_prefix" : true
            }
          }
        },
        "error" : {
          "type" : "string"
          ## エラーのように検索したいものは検索対象に
          ## 日本語を入れる場合はanalyzerにkuromojiとか指定する
        }
        ### --- ここまで --- ###
      }
    }
  }
}

当将mapping添加后,允许每个元素不存在,如果有未指定的元素出现,则视为不符合要求。为了解决上层的一些固定问题,可以将不确定来自dump object的值放在params下面,这样很方便。

将此输入到elasticsearch中

curl -XPUT http://localhost:9200/_template/logstash -d @template

暫時準備完成了。
當日誌開始流動時,索引被以指定的範本形式存儲。

表演

    • テンプレートを使ったインデックス運用にした結果、例より複雑なマッピングを指定しても1台で秒間1000行とかは問題なく処理できている模様

 

    • ただログの保存期間が長くなってくると、今度はkibana上から飛んでくるrangeの広かったり、aggregationのインターバルが細かいsearchリクエストでelasticsearchが殺される問題が…

 

    • とりあえずは横に並べて問題回避

できればHEAPを食い尽くすようなリクエストをkillする仕組みがないか検討したい

广告
将在 10 秒后关闭
bannerAds