CBoard+ES 快速搭建自助交互式数据分析平台(BI)

背景

之前我们基于ES构建了内容中心的全站搜索,现在作品的制作情况也需要在前端BI层面进行交互分析,BI层的实时聚合部分我们采用ES来实现;为了不影响内容搜索业务的正常运行,我们选择新建一个集群来支撑上述功能,通过reindex操作实现跨集群数据同步;_reindex操作并不是es7.0才有的功能,通过这个操作可以快速实现索引的复制、重建、跨集群迁移

搭建流程

整个交互式数据分析平台分两部分构成:CBoard + ES。

图表操作界面

  • CBoard
    因本篇侧重ES的使用讲解,cboard细节可参看相关资料解决;cboard是一款开源的自助分析工具,主要分4部分组成,创建数据源(这里我们选用ES)> 创建数据集 > 创建图标 > 创建看板。因创建图表功能支持用户拖拉拽操作,所以这部分操作对用户来说非常简单;部署完该项目后基本不需要二次开发,启动后配置完数据源便可以使用;有难度的是自助分析需要有一个强大的实时计算引擎支撑;经测试ES可满足在现有数据的任意维度的聚合分析,图标的加载性能优化后可秒级响应。

  • ES
    a、数据同步;这里采用_reindex的方式每天增量从内容库迁移,配置如下:

POST _reindex?slices=5&refresh
{
  "source": {
     "remote": {   #配置需要抽取的ES源地址
      "host": "http://source_host:9200"
    },
    "index": ["scene_model","ls_model","print_model"],   # 指定从哪些数据索引中抽取数据
    "_source": ["code","cover","id", "product", "title", "create_time", "publish_time", "update_time", "total_pv" ,"total_uv" ,"total_form", "login_id", "user_reg_time"],   #执行抽取的维度,对应下面的mapping设置
    "size": 1000,    #抽取批次大小
    "query": {       #增量抽取昨天有过发布更新的数据
      "range": {
        "publish_time": {
          "gte": "now-1d/d"
        }
      }
    }
  },
  "dest": {
    "index": "work_model",  #目标索引名称
    "version_type": "external"  #类似upsert操作
  },
  "script": {
    "lang": "painless",
    "source": "ctx._id = ctx._index.substring('as2_'.length(), ctx._index.length()) + '_' + ctx._id  ;ctx._source.index = ctx._index.substring('as2_'.length(), ctx._index.length()) "    #因目标索引来自多个索引库的数据,为避免Id冲突,给目标索引增加对应的_index前缀
  }
}

b、mapping & setting

{
    "mappings" : {
        "dynamic" : "false", 
        "dynamic_templates" : [
          {
            "strings" : {
              "match_mapping_type" : "string",
              "mapping" : {
                "doc_values" : false,
                "norms" : false,
                "type" : "keyword"
              }
            }
          }
        ],
        "date_detection" : false,
        "properties" : {
          "biz_type" : {
            "type" : "keyword" 
          },
          "check_status" : {
            "type" : "keyword" ,
            "doc_values" : false
          },
          "code" : {
            "type" : "keyword" ,
            "doc_values" : false
          }, 
          "cover" : {
            "type" : "keyword",
            "index" : false,
            "doc_values" : false
          },
          "create_time" : {
            "type" : "date",
            "format" : "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
          },
          "create_user" : {
            "type" : "keyword" 
          }, 
          "enterprise" : {
            "type" : "keyword" 
          },
          "id" : {
            "type" : "keyword",
            "doc_values" : false
          },
          "is_del" : {
            "type" : "keyword",
            "doc_values" : false
          },
          "login_id" : {
            "type" : "keyword",
            "doc_values" : false
          },
          "member_type" : {
            "type" : "keyword" 
          },
          "product" : {
            "type" : "keyword",
            "doc_values" : false
          },
          "publish_time" : {
            "type" : "date",
            "format" : "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
          },
          "share_type" : {
            "type" : "keyword" 
          },
          "template_code" : {
            "type" : "keyword",
            "doc_values" : false
          },
          "template_title" : {
            "type" : "text",
            "index_options" : "freqs",
            "analyzer" : "eqs_analyzer",
            "search_analyzer" : "ik_smart"
          }, 
          "title" : {
            "type" : "text",
            "index_options" : "freqs", 
            "analyzer" : "eqs_analyzer",
            "search_analyzer" : "ik_smart"
          },
          "total_form" : {
            "type" : "integer",
            "ignore_malformed" : true
          },
          "total_pv" : {
            "type" : "integer",
            "ignore_malformed" : true
          },
          "total_spv" : {
            "type" : "integer",
            "ignore_malformed" : true
          },
          "total_uv" : {
            "type" : "integer",
            "ignore_malformed" : true
          },
          "update_time" : {
            "type" : "date",
            "format" : "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
          },
          "user_name" : {
            "type" : "keyword",
            "doc_values" : false
          },
          "user_phone" : {
            "type" : "keyword" 
          },
          "user_type" : {
            "type" : "keyword" 
          },
          "yesterday_pv" : {
            "type" : "integer",
            "ignore_malformed" : true
          },
          "yesterday_uv" : {
            "type" : "integer",
            "ignore_malformed" : true
          }
        }
      }
    },
    "settings" : {
      "index" : {
        "refresh_interval" : "120s",
        "translog" : {
          "flush_threshold_size" : "1024mb",
          "sync_interval" : "120s",
          "durability" : "async"
        }, 
        "max_result_window" : "20000", 
        "store" : {
          "type" : "niofs"
        },
        "unassigned" : {
          "node_left" : {
            "delayed_timeout" : "1d"
          }
        },
        "analysis" : {
          "analyzer" : {
            "eqs_highlight_analyzer" : {
              "filter" : [
                "unique"
              ],
              "type" : "custom",
              "tokenizer" : "letter"
            },
            "eqs_analyzer" : {
              "filter" : [
                "unique"
              ],
              "char_filter" : [
                "html_strip"
              ],
              "type" : "custom",
              "tokenizer" : "ik_max_word"
            }
          }
        },
        "number_of_replicas" : "0",
       
        "codec" : "best_compression",
        "routing" : {
          "allocation" : {
            "total_shards_per_node" : "10"
          }
        },
        "search" : {
          "slowlog" : {
            "level" : "info",
            "threshold" : {
              "fetch" : {
                "info" : "500ms"
              },
              "query" : {
                "info" : "1s"
              }
            }
          }
        },
        "number_of_shards" : "8",
        "merge" : {
          "scheduler" : {
            "max_thread_count" : "2"
          }
        }
      }
    }
  
}

未完待续~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容