对于多属性类型系统的数据库设计

主要是以下几类系统:

  1. 生活信息系统, 内容:小, 属性:大,
  2. 电商商品系统, 内容:大, 属性:大,
  3. 风控征信系统, 内容:小, 属性:大,
  4. 新闻系统, 内容:大, 属性:小,

这些系统共同的特点, 都是在主体内容上会携带多个属性, 并且属性需要随时能调整, 并且要求能兼容旧属性, 还需要频繁的通过属性组合进行检索.

对于属性的管理, 可以参考58同城的这个解决方案

https://mp.weixin.qq.com/s?__biz=MjM5ODYxMDA5OQ==&mid=2651959855&idx=1&sn=f33abe8ec598c273f29cebb9365ece59

其方式, 就是通过JSON化的字段, 来避免使用纵表, 这样可以i减轻开发的工作量, 以及实际运行时的数据量. 在这个之上, 使用一些手段压缩了JSON字段的尺寸, 以及通过属性, 属性分组, 属性枚举等结构增加了数据的灵活性. 在搜索上, 58是使用自研的系统, 这个在普通应用中可以使用elastic search代替.

另外关于电商SKU的数据设计, 也可以采用上面的方式避免纵表带来的巨大记录数量. SKU一般是按 产品分类, 产品, 产品SKU, 属性分组, 属性, 属性枚举 这样的结构来实现业务数据管理的.

可以参考这篇里面的说明 http://www.cnblogs.com/winstonyan/archive/2012/01/07/b2c_research_product_sku_analyse_design2.html

 

携程在Elastic Search上的介绍

【携程旅行网 吴晓刚】
ElasticSearch目前在互联网公司主要用于两种应用场景,其一是用于构建业务的搜索功能模块且多是垂直领域的搜索,数据量级一般在千万至数十亿这个级别;其二用于大规模数据的实时OLAP,经典的如ELKStack,数据规模可能达到千亿或更多。 这两种场景的数据索引和应用访问模式上差异较大,在硬件选型和集群优化方面侧重点也会有所不同。一般来说后一种场景属于大数据范畴,数据量级和集群规模更大,在管理方面也更有挑战。

应Medcl大大的邀请,为ES中文社区做今年的Advent开篇,分享一下我在管理自家公司用于日志分析的ES集群方面的一点心得,蜻蜓点水,泛泛而谈,希望大方向上能对大家提供一些帮助。

这里的自家,即是携程旅行网。从2013年开始接触ES,我们团队先后实践过0.9.x -> 5.0.0中间各个版本,从最初只用于运维内部IIS日志的分析,到如今支持IT、呼叫中心、安全、测试、业务研发等多个部门超过200种日志型数据的实时检索与分析。 一路走来,愉悦了大家,也死磕了自己。

目前我们最大的日志单集群有120个data node,运行于70台物理服务器上。数据规模如下:
单日索引数据条数600亿,新增索引文件25TB (含一个复制片则为50TB)
业务高峰期峰值索引速率维持在百万条/秒
历史数据保留时长根据业务需求制定,从10天 - 90天不等
集群共3441个索引、17000个分片、数据总量约9300亿, 磁盘总消耗1PB
Kibana用户600多人, 每日来自Kibana和第三方的API调用共63万次
查询响应时间百分位 75%:0.160s 90%:1.640s 95%:6.691s 99%:14.0039s

运维这样大规模的ES集群,有哪些值得注意的地方?

一. 必不可少的工具
工欲善其事必先利其器,从一开始,哪怕就只有几个node,就应该使用分布式配置管理工具来做集群的部署。随着应用的成熟,集群规模的逐步扩大,效率的提升会凸显。 官方提供了ES Puppet Module和Chef Cookbook,熟悉这两个工具的同学可以直接拿过来用。 我们自己则是采用的Ansible,编写了一套Playbook来达到类似的效果。 用熟这类工具,对于集群的初始部署,配置批量更改,集群版本升级,重启故障结点都会快捷和安全许多。
第二个必备利器就是sense插件。通过这个插件直接调用集群的restful API,在做集群和索引的状态查看,索引配置更改的时候非常方便。语法提示和自动补全功能更是实用,减少了翻看文档的频率。在Kibana5里面,sense已经成为一个内置的控制台,无需额外安装。

二. 硬件配置
我们采用的是32vcoreCPU + 128GB RAM的服务器,磁盘配置大部分服务器是12块4TB SATA机械磁盘做的Raid0,少部分机器是刚上了不久的6块800GB SSD raid0,主要目的是想做冷热数据分离,后面谈到集群架构的时候,再进一步解释一下如何利用硬件资源。

三. 集群的管理
首先很有必要对ES的结点做角色划分和隔离。大家知道ES的data node除了放数据以外,也可以兼任master和client的角色,多数同学会将这些角色混入到data node。然而对于一个规模较大,用户较多的集群,master和client在一些极端使用情况下可能会有性能瓶颈甚至内存溢出,从而使得共存的data node故障。data node的故障恢复涉及到数据的迁移,对集群资源有一定消耗,容易造成数据写入延迟或者查询减慢。如果将master和client独立出来,一旦出现问题,重启后几乎是瞬间就恢复的,对用户几乎没有任何影响。另外将这些角色独立出来的以后,也将对应的计算资源消耗从data node剥离出来,更容易掌握data node资源消耗与写入量和查询量之间的联系,便于做容量管理和规划。
避免过高的并发,包括控制shard数量和threadpool的数量。在写入量和查询性能能够满足的前提下,为索引分配尽量少的分片。分片过多会带来诸多负面影响,例如:每次查询后需要汇总排序的数据更多;过多的并发带来的线程切换造成过多的CPU损耗;索引的删除和配置更新更慢Issue#18776; 过多的shard也带来更多小的segment,而过多的小segment会带来非常显著的heap内存消耗,特别是如果查询线程配置得很多的情况下。 配置过大的threadpool更是会产生很多诡异的性能问题Issue#18161里所描述的问题就是我们所经历过的。 默认的Theadpool大小一般来说工作得很不错了。
冷热数据最好做分离。对于日志型应用来说,一般是每天建立一个新索引,当天的热索引在写入的同时也会有较多的查询。如果上面还存有比较长时间之前的冷数据,那么当用户做大跨度的历史数据查询的时候,过多的磁盘IO和CPU消耗很容易拖慢写入,造成数据的延迟。所以我们用了一部分机器来做冷数据的存储,利用ES可以给结点配置自定义属性的功能,为冷结点加上"boxtype":"weak"的标识,每晚通过维护脚本更新冷数据的索引路由设置index.routing.allocation.{require|include|exclude},让数据自动向冷结点迁移。 冷数据的特性是不再写入,用户查的频率较低,但量级可能很大。比如我们有个索引每天2TB,并且用户要求保持过去90天数据随时可查。保持这么大量的索引为open状态,并非只消耗磁盘空间。ES为了快速访问磁盘上的索引文件,需要在内存里驻留一些数据(索引文件的索引),也就是所谓的segment memory。稍微熟悉ES的同学知道,JVM heap分配不能超过32GB,对于我们128GB RAM, 48TB磁盘空间的机器而言,如果只跑一个ES实例,只能利用到32GB不到的heap,当heap快用饱和的时候,磁盘上保存的索引文件还不到10TB,这样显然是不经济的。 因此我们决定在冷结点上跑3个ES实例,每个分配31GB heap空间,从而可以在一台物理服务器上存储30多TB的索引数据并保持open状态,供用户随时搜索。 实际使用下来,由于冷数据搜索频率不高,也没有写入,即时只剩余35GB内存给os做文件系统缓存,查询性能还是可以满足需求的。
不同数据量级的shard最好隔离到不同组别的结点。 大家知道ES会自己平衡shard在集群的分布,这个自动平衡的逻辑主要考量三个因素。其一同一索引下的shard尽量分散到不同的结点;其二每个结点上的shard数量尽量接近;其三结点的磁盘有足够的剩余空间。这个策略只能保证shard数量分布均匀,而并不能保证数据大小分布均匀。 实际应用中,我们有200多种索引,数据量级差别很大,大的一天几个TB,小的一个月才几个GB,并且每种类型的数据保留时长又千差万别。抛出的问题,就是如何能比较平衡并充分的利用所有节点的资源。 针对这个问题,我们还是通过对结点添加属性标签来做分组,结合index routing控制的方式来做一些精细化的控制。尽量让不同量级的数据使用不同组别的结点,使得每个组内结点上的数据量比较容易自动平衡。
定期做索引的force merge,并且最好是每个shard merge成一个segment。前面提到过,heap消耗与segment数量也有关系,force merge可以显著降低这种消耗。 如果merge成一个segment还有一个好处,就是对于terms aggregation,搜索时无需构造Global Ordinals,可以提升聚合速度。

四. 版本选择
我们在2.4版本上稳定跑了很长时间,比较保守的同学可以上2.4,激进有精力折腾的可以考虑最新的5.0。 我们集群两周前从v2.4.0升级到了v5.0.0这个版本,除了升级第一周遇到一个不稳定的问题以外,感觉新版本带来的以下特性还是非常值得去升级的:
结点启动的Bootstrap过程加入了很多关键系统参数设置的核验,比如Max File Descriptors, Memory Lock, Virtual Memory设置等等,如果设置不正确会拒绝启动并抛出异常。 与其带着错误的系统参数启动,并在日后造成性能问题,不如启动失败告知用户问题,是个很好的设计!
索引性能提升。升级后在同样索引速率下,我们看到cpu消耗下降非常明显,除了对索引速率提升有帮助,也会一定程度提升搜索速率。
新的数值型数据结构,存储空间更小,Range和地理位置计算更快速
Instant Aggregation对于类似now-7d to now这样的范围查询聚合能够做cache了,实际使用下来,效果明显,用户在Kibana上跑个过去一周数据的聚合,头2次刷新慢点,之后有cache了几乎就瞬间刷出!
更多的保护措施保证集群的稳定,比如对一次搜索hit的shard数量做了限制,增强了circuit breaker的特性,更好的防护集群资源被坏查询耗尽。

升级第一周,我们的冷数据结点出现间歇性不响应问题,从而刨出3个issue提交给官方:
Issue#21595 Issue#21612 Issue#21611
第一个问题确认为Bug,将在5.0.2修复,其他两个目前还不清楚根源,看起来也只在我们的应用场景里遇到了。所幸问题都找到了了规避措施,实施这些措施以后,最近一周我们的集群重新回到以前2.4版本时期的稳定状态。


五. 监控
不差钱没空折腾的建议还是买官方的xpack省心,有精力折腾的,利用ES各种丰富的stats api,用自己熟悉的监控工具采集数据,可视化出来就好了。 那么多监控指标,最最关键的还是以下几类:
各类Thread pool的使用情况,active/queue/reject可视化出来。 判断集群是否有性能瓶颈了,看看业务高峰期各类queue是不是很高,reject是不是经常发生,基本可以做到心里有数。
JVM的heap used%以及old GC的频率,如果old GC频率很高,并且多次GC过后heap used%几乎下不来,说明heap压力太大,要考虑扩容了。(也有可能是有问题的查询或者聚合造成的,需要结合用户访问记录来判断)。
Segment memory大小和Segment的数量。节点上存放的索引较多的时候,这两个指标就值得关注,要知道segment memory是常驻heap不会被GC回收的,因此当heap压力太大的时候,可以结合这个指标判断是否是因为节点上存放的数据过多,需要扩容。Segement的数量也是比较关键的,如果小的segment非常多,比如有几千,即使segment memory本身不多,但是在搜索线程很多的情况下,依然会吃掉相当多的heap,原因是lucene为每个segment会在thread local里记录状态信息,这块的heap内存开销和(segment数量* thread数量)相关。
很有必要记录用户的访问记录。我们只开放了http api给用户,前置了一个nginx做http代理,将用户第三方api的访问记录通过access log全部记录下来。通过分析访问记录,可以在集群出现性能问题时,快速找到问题根源,对于问题排查和性能优化都很有帮助。

最后就是多上手实践,遇到问题多查官方资料,多Google看是否有其他人遇到同类问题,精力充足有编程背景的同学也可以多刨刨源码。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/254060.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux环境部署常用命令

1.  查看当前所属目录:pwd2.  回到上级目录:cd ../回到上两级目录:cd ../ ../3.  查看当前目录下有哪些文件:ls4.  查看最后100行日志:tail -100 catalina.out动态重看操作日志:tail -f catalina.o…

DM6446开发攻略:V4L2视频驱动和应用分析

针对DAVINCI DM6446平台,网络上也有很多网友写了V4L2的驱动,但只是解析Montavistalinux-2.6.10 V4L2的原理、结构和函数,深度不够。本文决定把Montavista 的Linux-2.6.18 V4L2好好分析一下,顺便讲解在产品中的应用,满足…

相机像素尺寸(像元大小)和成像系统分辨率之间的关系

相机像素尺寸(像元大小)和成像系统分辨率之间的关系 在显微成像系统中,常常会用分辨率来评价其成像能力的好坏。这里的分辨率通常是指光学系统的极限分辨率以及成像探测器的图像分辨率。最终图像所呈现出的实际分辨率,取决于二者的…

H5网页播放器播不了服务器上的mp4视频文件

打开IIS,在功能视图里找到MIME类型菜单,打开该菜单后鼠标右键添加.mp4扩展名的MIME类型video/mp4 其他视频文件播放不了估计也得在IIS里添加对应的MIME类型(从服务器下载文件时也得添加对应的MIME类型) 转载于:https://www.cnblog…

不定宽度居中

一、传统方法 <div class"wrap"><div class"inner">html &#xff1a; 让 inner 居中</div> </div> .wrap {float: left; /* 自适应内容宽度 */position: relative;left: 50%; } .inner {position: relative;left: -50%; } 二、…

文章目录自动生成器

提供一个插件&#xff0c;可以实现segmentfault的文章目录效果啦~~ 不止点击跳转还滚动激活当前链接 demo地址 使用很简单 <!-- 文章容器 --> <div id"kCatelog"></div> <!-- 目录容器 --> <div class"k-catelog-list" id"…

基于ARM+DSP进行应用开发-经验共享

针对当前应用的复杂性&#xff0c;SOC芯片更好能能满足应用和媒体的需求&#xff0c;集成众多接口&#xff0c;用ARM做为应用处理器进行多样化的应用开发和用户界面和接口&#xff0c;利用DSP进行算法加速&#xff0c;特别是媒体的编解码算法加速&#xff0c;既能够保持算法的灵…

工业相机之全局曝光与卷帘曝光

曝光方式包括两种&#xff1a; 全局曝光&#xff08;global shutter&#xff09;卷帘曝光&#xff08;rolling shutter&#xff09; CCD相机都是全局曝光&#xff0c;CMOS相机既有全局曝光也有卷帘曝光 全局曝光 全局曝光的方式比较简单。也就是说光圈打开后&#xff0c;整个图…

Hibernate入门注解笔记

Entity 代表实体 映射一张表 Table 定义表的属性 Embeddable 定义类级别可以被嵌入 Id 指定主键 GeneratedValue 指定主键生成策略 Column指定列级别的属性 Embedded 指定属性为被包含类 将被包含类 作为 包含类的 字段属性 写入同一张表 EmbeddedId 指定包含类为特定主键 实…

.NET 环境中使用RabbitMQ

在企业应用系统领域&#xff0c;会面对不同系统之间的通信、集成与整合&#xff0c;尤其当面临异构系统时&#xff0c;这种分布式的调用与通信变得越发重要。其次&#xff0c;系统中一般会有很多对实时性要求不高的但是执行起来比较较耗时的地方&#xff0c;比如发送短信&#…

css3 pointer-events:none 允许点击穿透

开发时加了蒙层&#xff0c;却可以点击到蒙层下边的元素。查了以后才发现是 pointer-events:none属性具有允许点击穿透的功能&#xff0c;将其设为 pointer-events:auto就好使了。事件穿透让我想起了zepto.js中的tap事件同样会引发事件穿透的效果。如果用tap事件是为了提升响应…

成像质量、像素个数、感光元件尺寸的关系

成像质量、像素个数、感光元件尺寸的关系 感光元件 (影像传感器) 就是拍摄的照片最终成像的位置。相当于传统相机里面的胶卷&#xff0c;不同相机的感光元件尺寸是不一样的。 1. 像素的含义 两个 100 平方米的房子 A 和 B&#xff0c;A 房子里面平均分成 10 个房间&#xff…

setjmp与logjmp用法总结

setjmp/logjmp的最大用途是错误恢复&#xff0c;只要还没有从主函数退出&#xff0c;一旦发现一个不可恢复的错误&#xff0c;可以把主控制转移大主函数循环&#xff0c;并从那从新开始。使用时必须包含头文件<setjmp.h> setjmp与longjmp结合使用时&#xff0c;它们必须…

JQ对象到底是什么

jQuery对象是什么&#xff0c;举个例子&#xff0c;$(#id) 返回的就是jQuery对象&#xff0c;这个东西是整个jQuery的核心所在&#xff0c;所以我先来分析它。 var jQuery function( selector, context ) { // The jQuery object is actually just the init constructor enhan…

15、iOS开发之duplicate symbols for architecture x86_64错误

1. 错误提示 2. 分析错误原因 3. 解决问题办法 一、错误提示 在我们写代码过程中可能会经常遇到这样一个错误&#xff1a; [objc] view plaincopy print?<span style"font-size:32px;color:#ff0000;">ld: 4 duplicate symbols for architecture x86_64 clang…

【死磕Java并发】----- 死磕 Java 并发精品合集

【死磕 Java 并发】系列是 LZ 在 2017 年写的第一个死磕系列&#xff0c;一直没有做一个合集&#xff0c;这篇博客则是将整个系列做一个概览。 先来一个总览图&#xff1a; 【高清图&#xff0c;请关注“Java技术驿站”公众号&#xff0c;回复&#xff1a;脑图JUC】 【死磕Java…

vs官方使用教程中文版与英文版

Visual Studio IDE 中文文档 https://docs.microsoft.com/zh-cn/visualstudio/ide/ Visual Studio IDE documentation https://docs.microsoft.com/en-us/visualstudio/ide/

linux subsys_initcall

宏定义__define_initcall(level,fn)对于内核的初始化很重要&#xff0c;他指示编译器在编译的时候&#xff0c;将一系列初始化函数的起始地址值按照一定的顺序放在一个section中。在内核初始化段&#xff0c;do_initcalls() 将按顺序从该section中以函数指针的形式取出这些函数…

vue transition

Vue.js 教程 (9) : 过渡动画 Vue.js 提供非常简单的过渡动画接口。这些过渡动画在 Vue.js 将目标元素插入或移除出 DOM 的时候会自动执行。能够触发动画的指令包括 v-if , v-show 和 v-repeat。同时&#xff0c;vm 实例的 $appendTo() , $before() , $after() 和 $remove() 方法…

VS扩展工具

原文发布时间为&#xff1a;2011-03-09 —— 来源于本人的百度文章 [由搬家工具导入]http://visualstudiogallery.msdn.microsoft.com/site/search?f%5B0%5D.TypeRootCategory&f%5B0%5D.Valuetools转载于:https://www.cnblogs.com/handboy/p/7163982.html