范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

架构师必备多维度查询的最佳实践

  背景
  有2种常见的多维度查询场景,分别是: 带多个筛选条件的列表查询 不含分库分表列的其他维度查询
  普通的数据库查询,很难实现上述需求场景,更不用提模糊查询、全文检索了。
  下面结合楼主的经验和知识,介绍初级方案、进阶方案(上ElasticSearch),大部分情况下推荐使用ElasticSearch来实现多维度查询,赶时间的读者可以直接跳到"进阶方案:将ElasticSearch添加到现有系统中"。 初级方案1、根据常见查询场景,增加相应字段的组合索引
  这个是为了实现带多个筛选条件的列表查询的。 优点非常简单 读写不一致时间较短:取决于数据库主从同步延时,一般为毫秒级别 缺点非常局限:除非筛选条件比较固定,否则难以应付后续新增或修改筛选条件 如果每次来新的筛选查询字段的需求,就新增索引,最终导致索引过于庞大,影响性能
  于是就出现了经典的一幕:产品提需求说要支持某个新字段的筛选查询,开发反馈说做不了、或者成本很高,于是不了了之 :) 2、异构出多份数据
  更加优雅的方式,是异构出多份数据。
  例如,C端按用户维度查询,B端按店铺维度查询,如果还有供应商,按供应商维度查询。一个数据库只能按一种维度来分库。 (1)程序写入多个数据源
  优点是:非常简单。 缺点跨库写存在一致性问题(除非不同维度的表使用公共的分库,事务写入),性能低 不能灵活支持更多其他维度的查询 (2)借助Canal实现数据的自动同步
  通过Canal同步数据,异构出多个维度的数据源。详见之前写的这篇文章:架构师必备:巧用Canal实现异步、解耦的架构
  优点是:更加优雅,无需改动程序主流程。 缺点仍然无法解决不断变化的需求,不可能为了支持新维度就异构出一份新数据 进阶方案:将ElasticSearch添加到现有系统中应用架构
  现有系统一般都会用到MySQL数据库,需要引入ES,为系统增强多维度查询的功能。
  MySQL继续承担业务的实时读写请求、事务操作,ES承担近实时的多维度查询请求,ES可支撑十万级别qps(取决于节点数、分片数、副本数)。
  需要注意的是:同步数据至ES是秒级延迟(主要耗费在索引refresh),而查询已进入索引的文档,是在数毫秒到数百毫秒级别。
  导入数据
  需要同步机制,来把MySQL中的数据导入到ES中,主要流程如下: 预先定义ES索引的mapping配置,而不依赖ES自动生成mapping 初始全量导入,后续增量导入:Canal+MQ数据管道同步,不需要或仅需少量代码工作 数据过滤:不导入无需检索的字段,减小索引大学,提高性能 数据扁平化处理:如果数据库中有json字段列,需要从中提取业务字段,避免嵌套类型的字段,提高性能
  查询数据从ES 8.x版本开始, 建议使用Java api client ,并且要Java 8及以上环境,因为可使用各种lambda函数,来提高代码可读性 优点是新客户端与server代码完全耦合(相比于原Java transport client,在8.x版本已废弃),并且API风格与http rest api很接近(相比于原Java rest client,在8.x版本已废弃),只要熟练掌握http json请求体写法,即可快速上手。 底层使用的还是原来的low level rest client,实现了http长连接、访问ES各节点的负载均衡、故障转移,最底层依赖的是apache http async client。 ES 7.x版本及以下,或使用Java 7及以下,建议升级,否则就只能继续用high level rest client。
  代码示例如下(含详细注释): public class EsClientDemo {      // demo演示:创建client,然后搜索     public void createClientAndSearch() throws Exception {         // 创建底层的low level rest client,连接ES节点的9200端口         RestClient restClient = RestClient.builder(             new HttpHost("localhost", 9200)).build();          // 创建transport类,传入底层的low level rest client,和json解析器         ElasticsearchTransport transport = new RestClientTransport(             restClient, new JacksonJsonpMapper());          // 创建核心client类,后续操作都围绕此对象         ElasticsearchClient esClient = new ElasticsearchClient(transport);           // 多条件搜索         // fluent API风格,并且使用lambda函数提高代码可读性,可以看出Java api client的语法,同http json请求体非常相似         String searchText = "bike";         String brand = "brandNew";         double maxPrice = 1000;          // 根据商品名称,做match全文检索查询         Query byName = MatchQuery.of(m -> m             .field("name")             .query(searchText)         )._toQuery();          // 根据品牌,做term精确查询         Query byBrand = new Query.Builder()             .term(t -> t                                           .field("brand")                                     .value(v -> v.stringValue(brand))             ).build();          // 根据价格,做range范围查询         Query byMaxPrice = RangeQuery.of(r -> r             .field("price")             .lte(JsonData.of(maxPrice))         )._toQuery();          // 调用核心client,做查询         SearchResponse response = esClient.search(s -> s             .index("products")  // 指定ES索引             .query(q -> q       // 指定查询DSL                 .bool(b -> b    // 多条件must组合,必须同时满足                     .must(byName)                     .must(byBrand)                     .must(byMaxPrice)                 )             ),             Product.class         );          // 遍历命中结果         List> hits = response.hits().hits();         for (Hit hit: hits) {             Product product = hit.source();  // 通过source获取结果             logger.info("Found product " + product.getName() + ", score " + hit.score());         }     }  }
  可参阅:https://www.elastic.co/guide/en/elasticsearch/client/index.html 数据模型转换
  因为既有MySQL,又有ES,所以有2种异构的数据模型。需要在代码中定义2种数据模型,并且实现类型互相转换的工具类。 MySQL数据VO ES数据VO MySQL数据VO、ES数据VO互相转换工具 业务层BO 接口DTO 原理概要
  ES之所以比MySQL,能胜任多维度查询、全文检索,是因为底层数据结构不同: ES倒排索引如果是全文检索字段:会先分词,然后生成 term -> document 的倒排索引,查询时也会把query分词,然后检索出相关的文档。相关度算法如TF-IDF(term frequency–inverse document frequency),取决于:词在该文档中出现的频率(TF,term frequency),越高代表越相关;以及词在所有文档中出现的频率(IDF,inverse document frequency),越高代表越不相关,相当于是一个通用的词,对相关性影响较小。如果是精确值字段:则无需分词,直接把query作为一个整体的term,查询对应文档。 因为文档中的所有字段,都生成了倒排索引,所以能处理多维度组合查询 MySQL B+树B+树的非叶子节点记录了孩子节点值的范围,而叶子节点记录了真正的一组值,并且在同一层,形成了一个有序链表 组合索引需要显式创建:选择需索引的字段、并且顺序是重要的,所以如果待查询的字段不在索引中,就无法高效查询,可能演变为全表扫描 (对聚簇索引的叶子节点做一次遍历)
  另外简要回顾一下ES的架构要点: 节点分为主节点、数据节点,一个节点上可以有多个分片,分片分为主分片、副本分片,1对多,主分片与副本分片分布在不同的节点,来实现高可用 主分片数在创建时,就需要指定,在创建后不能随意更改(如果变化,路由就会出错);而副本分片可以增加,来提高ES集群的查询QPS 路由算法:id % 主分片数,如果创建文档时不指定id,则ES会自动生成;一般会传自定义业务id 优点、缺点优点支持各字段的多维度组合查询,无惧未来新增字段(主要成本在于新增字段后、重建索引) 与现有系统完全解耦,适合架构演进 在数据量级上远胜Mysql,最大支持PB级数据的存储和查询 缺点读写不一致时间在秒级:因为有2个耗时阶段,一是同步阶段将数据从MySQL数据库写入ES,二是ES索引refresh阶段,数据从buffer写入索引后才可查到因此一个trick就是,在写入操作后,前端延迟调用后端的列表查询接口,比如延迟1秒后再展示 超高并发下存在瓶颈,存在稳定性问题:目前原生版本支持大约 3-5 万分片,性能已经到达极限,创建索引基本到达 30 秒+ 甚至分钟级。节点数只能到 500 左右基本是极限了。但依然能满足绝大部分场景。数据来源:https://elasticsearch.cn/slides/259#page=30 ES最佳实践只把需要搜索的数据导入ES,避免索引过大 数据扁平化,不用嵌套结构,提高性能 合理设置字段类型,预先定义mapping配置,而不依赖ES自动生成mapping 精确值的类型指定为keyword(mapping配置),并且使用term查询精确值是指无需进行range范围查询的字段,既可以是字符串,比如书的作者名字,也可以是数值,比如商品id、订单id、图书ISBN编号、枚举值。在使用中,大部分场景是以id类作为精确值 避免无路由查询:无路由查询会并发在多个索引上查询、归并排序结果,会使得集群cpu飙升,影响稳定性 避免深度分页查询:如有大量数据查询,推荐用scroll滚动查询 设置合理的文件系统缓存(filesytem cache)大小,提高性能:因为ES查询的热数据在文件系统缓存中 ES分片数在创建后不能随意改动,但是副本数可以随时增加,来提高最大QPS。如果单个分片压力过大,需要扩容。 更进一步
  前面提到ES超高并发下存在瓶颈,极端情况下可能遇到OOM,因此超高并发下需要C++实现的专用搜索引擎
  例如: 百度:通用搜索引擎,根据文字、图片搜索信息 电商垂类:电商专用搜索引擎,比如根据关键词查找商品,或根据品牌、价格筛选商品,可总结为商品的搜索、广告、推荐

夸,夸,夸的超乎你想象!现在的广告五花八门,把各种产品吹上天,形形色色的红包游戏夸的比城市拆迁来钱快,让你玩到手软,玩到眼花。到账收入扔到地上没人捡。招工广告工资待遇每月两千的,为了让你提高积极性定位于2折叠收纳大吸力睿米NANO车载吸尘器随身带随手吸CiaoBella,我是老房。自从家里有了娃,原本只需一周一次的家庭大扫除,直接升级为一天多次都不够。尤其是在臭小子学会走路以后,简直就是一个行走的垃圾制造器,吃饭各种掉渣玩具到处一行代码搞定的事还用个锤子的PS啊作者豆豆来源Python技术在我们的日常生活和工作中有不少场景需要简单处下理图片,很多人都是依赖PS美图秀秀等各种图像处理工具,殊不知在你打开软件的一瞬间Python就已经将图片处预算30万以内,首选宝马X1和奥迪Q3林肯冒险家了解一下曾经奔驰注重乘坐舒适,宝马注重操控乐趣,奥迪注重科技氛围,而如今BBA内饰上大塑料已经司空见惯,特别是在入门款车型上内饰用料更是寒酸。预算在30万以内,如果在豪华品牌SUV领域当中在沃尔沃保养爱车,专业贴心,省时省力以往,消费者在选购汽车的时候最关注的当属汽车的外形性能动力舒适性等方面,这些项目直接影响大家在驾乘爱车时的体验。但随着人们用车需求的不断提升,更多消费者对于汽车的售后和保养也越来越沃尔沃v60表现如何?车主分享用车感受,原来v60如此优秀对于汽车产业来说,消费者的需求就是车企发展的方向。只有全面了解消费者的需求,车企才能制造出消费者喜爱的车型。作为一个对消费者需求洞察精准的车企,沃尔沃制造出了备受消费者喜爱的各种车提了沃尔沃轿车S60之后,车主觉得这车买的太值了选车是个挺麻烦的事,选定一个车型之后,你会发现市场上有很多同类型不同品牌的车。在挑选的过程中,很容易挑花眼。我最近在选车的时候就遇到了这样的情况,看看这个觉得不错,看看那个觉得也挺一次学会两种方式将pyton打成exe作者某某白米饭来源Python技术python可以做网站应用,也可以做客户端应用。但是客户端应用需要运行py脚本,如果用户不懂python就是一件比较麻烦的事情。幸好pyton有第新手必读真无线蓝牙耳机哪个好?三大奇招避开不良商家真无线蓝牙耳机一上线就备受关注,因为真无线蓝牙耳机简单易用,方便携带,加上很多真无线蓝牙耳机都配备了收纳盒,能够随时给耳机充电,再也不用担心总是没电了。那么真无线蓝牙耳机哪个好呢?真无线蓝牙耳机排行榜音质炸裂的五大爆款耳机真无线蓝牙耳机可以说是蓝牙耳机的终极形态了,左右耳塞之间也没有了线材的连接,更加便捷!今天小编结合使用过的几十款真无线蓝牙耳机,给大家整理了此次的音质排行榜,希望能帮到大家选购到称蔚来等车企回应特斯拉降价,国产新能源车有望崛起特斯拉在中国全面降价,降价后的价格直逼蔚来等面向高端市场的新能源车企,此前,造车新势力的代表,蔚来汽车创始人李斌就此事进行了回应。蔚来ES8蔚来汽车从2014年至今,蔚来的进步可圈
电信巨头康卡斯特为区块链启动Blockdaemon募集3亿美元种子轮据Blockdaemon首席执行官KonstantinRichter的中型邮件今天,3月7日,位于纽约的Blockchain初创公司Blockdaemon刚刚关闭了由电信集团Com真的有不留死角的洗地机?添可芙万二代深度体验来了对于地面清洁的要求,我还是比较高的,一直在追求用最少的精力保持家里的清洁。所以我经常在不断地尝试各种地面清洁设备吸尘器扫地机洗地机我都用过。所以,要聊起这个话题,自我感觉还是有一点关于盘点无人机行业还能与大疆抗衡的公司和机会一文的申明关于盘点无人机行业还能与大疆抗衡的公司和机会一文的申明最近有个别公司认为科技公众网或者作者是要故意贬低他们,频频联系我们找到作者释放出不那么友善的想法。在这里重申一下本文是科技公众年轻人拒绝去工厂上班,跑去送外卖,如何破局?年轻人拒绝去工厂上班,跑去送外卖,如何破局?推荐语2021年以来,国际市场能源价格在大幅度上涨,国内电力煤炭供需也在持续偏紧,多种因素共同导致广东浙江山东等地出台不同程度的限电措施又一打工怪象出现工厂包吃住不去,送外卖风里雨里却被追捧又一打工怪象出现工厂包吃住不去,送外卖风里雨里却被追捧推荐语众所周知,我国是一个拥有14亿人口的大国,劳动人口占比数量一直在全世界中更是稳居首位。但由于经济压力过大国人生育观念发生国庆假期景区人满为患,景区发明云旅游随着疫情的好转,各个旅游景区需要对外推广美好乡村的旅游风光,通过搭建远程视频管理平台,实时互动展现各个美好乡村的实时影像,让更多的旅游界朋友媒体朋友宣传景区推广景区,引导广大民众,前置眼部追焦更有神!华为nova7Pro助你成为朋友圈最靓仔愉快的五一小长假说来就来,对忙碌小半年的朋友们来说,此时正是在家享受生活的美好时刻,例如与许久不见的亲朋好友进行5G视频,或者晒自己日益精进的厨艺,收获满满的赞赏,多么惬意!要满足名企头条2020财富世界500强中国超美国中国共有133家公司上榜2020年财富世界500强中国财富世界500强数量首超美国8月10日,2020年财富世界500强排行榜揭晓。沃尔玛连续七年成为全球最大公司,中国共有133家公司上榜,首次超过美国。标准立项自主代客泊车地图与定位技术要求7月28日,中国汽车工程学会组织专家对中国智能网联汽车产业创新联盟(CAICV)提出的自主代客泊车地图与定位技术要求CSAE团体标准项目进行了立项审查,该标准由易图通科技(北京)有LK分享自动驾驶渐行渐近,高精地图商业化不断提速近年来,伴随着自动驾驶技术的快速发展以及智能网联汽车的日益落地,作为关键环节的高精地图发展逐渐迎来商业化契机。根据相关报告显示,目前我国高精地图市场总量已经来到4。74亿元,增速高LK分享2021年全球AI芯片行业市场现状及发展趋势分析随着人工智能技术日趋成熟,数字化基础设施不断完善,人工智能商业化应用将加速落地,推动AI芯片市场高速增长,预计2025年全球人工智能芯片市场规模将达726亿美元。随着大数据的发展和