1.mysql索引都有哪些原则? 索引的数据结构?B+ tree 和 B tree 有什么区别? www.cnblogs.com/tgycoder/p/… 建索引的几大原则 一、最左前缀匹配原则,很是重要的原则 mysql会一直向右匹配直到遇到范围查询(>、<、between、like)就中止匹配。好比a = 1 and b = 2 and c > 3 and d = 4,若是创建(a,b,c,d)顺序的索引,d是用不到索引的, 若是创建(a,b,d,c)的索引则均可以用到,a,b,d的顺序能够任意调整。php
二、=和in能够乱序
好比a = 1 and b = 2 and c = 3 创建(a,b,c)索引能够任意顺序,mysql的查询优化器会帮你优化成索引能够识别的形式。
三、尽可能选择区分度高的列做为索引
区分度的公式是count(distinct col)/count(*),表示字段不重复的比例,比例越大咱们扫描的记录数越少,惟一键的区分度是1,而一些状态、性别字段可能在大数据面前区分度就是0,那可 能有人会问,这个比例有什么经验值吗?使用场景不一样,这个值也很难肯定,通常须要join的字段咱们都要求是0.1以上,即平均1条扫描10条记录。
四、索引列不能参与计算,保持列“干净”
好比from_unixtime(create_time) = ’2014-05-29’就不能使用到索引,缘由很简单,b+树中存的都是数据表中的字段值,但进行检索时,须要把全部元素都应用函数才能比较,显然成本 太大。因此语句应该写成create_time = unix_timestamp(’2014-05-29’);
五、尽可能的扩展索引,不要新建索引
好比表中已经有a的索引,如今要加(a,b)的索引,那么只须要修改原来的索引便可。
六、若是肯定有多少条数据,使用 limit 限制一下,MySQL在查找到对应条数的数据的时候,会中止继续查找
七、利用查询缓存,不少时候MySQL会对查询结果进行cache,可是对应“动态”的数据会不cache,例如:
1 SELECT username FROM user WHERE signup_date >= CURDATE() 没法使用cache
2 SELECT username FROM user WHERE signup_date >= '2017-05-06' 能够cache
当使用了MySQL的一写函数以后,MySQL没法肯定结果是易变的,因此不会cache,还有now(),rand()
也同样不开启cache
八、join 语法,尽可能将小的表放在前面,在须要on的字段上,数据类型保持一致,并设置对应的索引,不然MySQL没法使用索引来join查询
九、在大表上作大量更新时,若是会锁全表,则须要拆分执行,避免长时间锁住表,致使其余请求积累太多(InnoDB 支持行锁,但前提是Where子句须要创建索引,没有索引也同样是锁全表)
为何要B+树
复制代码
因为B+树的数据都存储在叶子结点中,分支结点均为索引,方便扫库,只须要扫一遍叶子结点便可,可是B树由于其分支结点一样存储着数据,咱们要找到具体的数据,须要进行一次中序遍历按序来扫,因此B+树更加适合在区间查询的状况,因此一般B+树用于数据库索引,而B树则经常使用于文件索引。html
这都是因为B+树和B具备这不一样的存储结构所形成的区别,以一个m阶树为例。 关键字的数量不一样;B+树中分支结点有m个关键字,其叶子结点也有m个,其关键字只是起到了一个索引的做用,可是B树虽然也有m个子结点,可是其只拥有m-1个关键字。 存储的位置不一样;B+树中的数据都存储在叶子结点上,也就是其全部叶子结点的数据组合起来就是完整的数据,可是B树的数据存储在每个结点中,并不只仅存储在叶子结点上。 分支结点的构造不一样;B+树的分支结点仅仅存储着关键字信息和儿子的指针(这里的指针指的是磁盘块的偏移量),也就是说内部结点仅仅包含着索引信息。 查询不一样;B树在找到具体的数值之后,则结束,而B+树则须要经过索引找到叶子结点中的数据才结束,也就是说B+树的搜索过程当中走了一条从根结点到叶子结点的路径。 blog.csdn.net/bigtree_372…java
1.选择惟一性索引mysql
惟一性索引的值是惟一的,能够更快速的经过该索引来肯定某条记录。例如,学生表中学号是具备惟一性的字段。为该字段创建惟一性索引能够很快的肯定某个学生的信息。若是使用姓名的话,可能存在同名现象,从而下降查询速度。nginx
2.为常常须要排序、分组和联合操做的字段创建索引程序员
常常须要ORDER BY、GROUP BY、DISTINCT和UNION等操做的字段,排序操做会浪费不少时间。若是为其创建索引,能够有效地避免排序操做。web
3.为常做为查询条件的字段创建索引面试
若是某个字段常常用来作查询条件,那么该字段的查询速度会影响整个表的查询速度。所以,为这样的字段创建索引,能够提升整个表的查询速度。redis
4.限制索引的数目算法
索引的数目不是越多越好。每一个索引都须要占用磁盘空间,索引越多,须要的磁盘空间就越大。修改表时,对索引的重构和更新很麻烦。越多的索引,会使更新表变得很浪费时间。
5.尽可能使用数据量少的索引
若是索引的值很长,那么查询的速度会受到影响。例如,对一个CHAR(100)类型的字段进行全文检索须要的时间确定要比对CHAR(10)类型的字段须要的时间要多。
6.尽可能使用前缀来索引
若是索引字段的值很长,最好使用值的前缀来索引。例如,TEXT和BLOG类型的字段,进行全文检索会很浪费时间。若是只检索字段的前面的若干个字符,这样能够提升检索速度。
7.删除再也不使用或者不多使用的索引
表中的数据被大量更新,或者数据的使用方式被改变后,原有的一些索引可能再也不须要。数据库管理员应当按期找出这些索引,将它们删除,从而减小索引对更新操做的影响。
8 . 最左前缀匹配原则,很是重要的原则。
mysql会一直向右匹配直到遇到范围查询(>、<、between、like)就中止匹配,好比a 1=”” and=”” b=”2” c=”“> 3 and d = 4 若是创建(a,b,c,d)顺序的索引,d是用不到索引的,若是创建(a,b,d,c)的索引则均可以用到,a,b,d的顺序能够任意调整。
9 .=和in能够乱序。
好比a = 1 and b = 2 and c = 3 创建(a,b,c)索引能够任意顺序,mysql的查询优化器会帮你优化成索引能够识别的形式
10 . 尽可能选择区分度高的列做为索引。
区分度的公式是count(distinct col)/count(*),表示字段不重复的比例,比例越大咱们扫描的记录数越少,惟一键的区分度是1,而一些状态、性别字段可能在大数据面前区分度就 是0,那可能有人会问,这个比例有什么经验值吗?使用场景不一样,这个值也很难肯定,通常须要join的字段咱们都要求是0.1以上,即平均1条扫描10条 记录
11 .索引列不能参与计算,保持列“干净”。
好比from_unixtime(create_time) = ’2014-05-29’就不能使用到索引,缘由很简单,b+树中存的都是数据表中的字段值,但进行检索时,须要把全部元素都应用函数才能比较,显然成本 太大。因此语句应该写成create_time = unix_timestamp(’2014-05-29’);
12 .尽可能的扩展索引,不要新建索引。 好比表中已经有a的索引,如今要加(a,b)的索引,那么只须要修改原来的索引便可
注意:选择索引的最终目的是为了使查询的速度变快。上面给出的原则是最基本的准则,但不能拘泥于上面的准则。读者要在之后的学习和工做中进行不断的实践。根据应用的实际状况进行分析和判断,选择最合适的索引方式。 2.mysql有哪些存储引擎?有啥区别?要详细! MyISAM存储引擎:不支持事务、也不支持外键,优点是访问速度快,对事务完整性没有 要求或者以select,insert为主 InnoDB存储引擎提供了具备提交、回滚和崩溃恢复能力的事务安全。可是对比MyISAM引擎,写的处理效率会差一些,而且会占用更多的磁盘空间以保留数据和索引。 InnoDB存储引擎的特色:支持自动增加列,支持外键约束 Memory存储引擎使用存在于内存中的内容来建立表。每一个memory表只实际对应一个磁盘文件,格式是.frm。memory类型的表访问很是的快,由于它的数据是放在内存中的,而且默认使用HASH索引,可是一旦服务关闭,表中的数据就会丢失掉 Merge存储引擎是一组MyISAM表的组合,这些MyISAM表必须结构彻底相同,merge表自己并无数据,对merge类型的表能够进行查询,更新,删除操做,这些操做其实是对内部的MyISAM表进行的
3.设计高并发系统数据库层面如何设计?数据库锁有哪些类型?如何实现? www.cnblogs.com/zhangj391/p… blog.csdn.net/tangkund321… www.cnblogs.com/bcphp/p/768… 分库分表 读写分离 数据库高可用 数据分级 粗细管道 (表层面 不用外键关联 慢sql优化 索引等)
共享锁S LOCK 容许事务读一行数据 排他锁 X LOCK 容许事务删除或更新一行数据 page-level locking(页级锁) 锁定表中某些行集合(称作页),被锁定的行只对锁定最初的线程是可行。若是另一个线程想要向这些行写数据,它必须等到锁被释放。 ——————— InnoDB的锁大体分为: 3.1 行锁 支持并发高,带来最大的锁开销. 在存储引擎层实现,服务器感知不到 3.2 表锁 服务器会为诸如: ALTER Table 之类的语句使用表锁,忽略存储引擎的锁机制 但锁的类型又分为: (1). 共享锁(S Lock) , 容许事务读取一行数据 (2). 排他锁(X Lock),容许事务删除或更新一行数据.
分库分表 1.如何设计动态扩容的分库分表方案? blog.csdn.net/ht99582/art… 2.用过哪些数据库分表的中间件,有啥有点和缺点?分库分表中间件的设计原理 www.cnblogs.com/wangzhongqi… blog.csdn.net/kingice1014… 不管使用哪一种架构,核心逻辑均极为类似,除了协议实现层不一样(JDBC或数据库协议),都会分为分片规则配置、SQL解析、SQL改写、SQL路由、SQL执行以及结果归并等模块。 3.我如今有一个未分库分表的系统,之后系统需分库分表,如何设计? www.cnblogs.com/fjwuyongzhi… 让未分库分表的系统切换到分表的系统上
4.分布式事务如何解决?TCC?若是出现网络问题怎么办? www.cnblogs.com/taiyonghai/… 1、结合MQ消息中间件实现的可靠消息最终一致性 2、TCC补偿性事务解决方案(二阶段提交,设置好回滚) 3、最大努力通知型方案
第一种方案:可靠消息最终一致性,须要业务系统结合MQ消息中间件实现,在实现过程当中须要保证消息的成功发送及成功消费。即须要经过业务系统控制MQ的消息状态 第二种方案:TCC补偿性,分为三个阶段TRYING-CONFIRMING-CANCELING。每一个阶段作不一样的处理。(2阶段提交,设置好回滚) TRYING阶段主要是对业务系统进行检测及资源预留 CONFIRMING阶段是作业务提交,经过TRYING阶段执行成功后,再执行该阶段。默认若是TRYING阶段执行成功,CONFIRMING就必定能成功。 CANCELING阶段是回对业务作回滚,在TRYING阶段中,若是存在分支事务TRYING失败,则须要调用CANCELING将已预留的资源进行释放。 第三种方案:最大努力通知xing型,这种方案主要用在与第三方系统通信时,好比:调用微信或支付宝支付后的支付结果通知。这种方案也是结合MQ进行实现,例如:经过MQ发送http请求,设置最大通知次数。达到通知次数后即再也不通知。 具体的案例你也能够参考下这篇博客,它上面的这个案例就是结合电商支付作的系统分布式事务实现案例:www.roncoo.com/article/det…
基于事务消息的MQ方案是目前公认的较为理想的分布式事务解决方案,各大电商都在应用这一方案。种方式适合的业务场景普遍,并且比较可靠。不过这种方式技术实现的难度比较大。目前主流的开源MQ(ActiveMQ、RabbitMQ、Kafka)均未实现对事务消息的支持,因此需二次开发或者新造轮子。 www.cnblogs.com/taiyonghai/… 5.为何要分库分表? 单表容量有限 系统分离,不能以挂全挂 6.分布式寻址方式有哪些算法?一致性hash知道吗?
7.如何解决分库分表主键问题?有什么实现方案? 分布式主键生成策略 www.jianshu.com/p/a0a3aa888…
代码更清晰,处理逻辑更简单 不用去考虑各类锁的问题,不存在加锁释放锁操做,没有由于可能出现死锁而致使的性能消耗 不存在多进程或者多线程致使的切换而消耗CPU
2.redis有什么数据类型?在哪些场景下使用? String 应用场景:String是最经常使用的一种数据类型,普通的key/ value 存储均可以归为此类.便可以彻底实现目前 Memcached 的功能,而且效率更高。还能够享受Redis的定时持久化,操做日志及 Replication等功能。除了提供与 Memcached 同样的get、set、incr、decr 等操做外,Redis还提供了下面一些操做: 获取字符串长度 往字符串append内容 设置和获取字符串的某一段内容 设置及获取字符串的某一位(bit) 批量设置一系列字符串的内容 Hash 经常使用命令:hget,hset,hgetall 等。 应用场景:在Memcached中,咱们常常将一些结构化的信息打包成HashMap,在客户端序列化后存储为一个字符串的值,好比用户的昵称、年龄、性别、积分等,这时候在须要修改其中某一项时,一般须要将全部值取出反序列化后,修改某一项的值,再序列化存储回去。这样不只增大了开销,也不适用于一些可能并发操做的场合(好比两个并发的操做都须要修改积分)。而Redis的Hash结构能够使你像在数据库中Update一个属性同样只修改某一项属性值。 List 好比twitter的关注列表,粉丝列表等均可以用Redis的list结构来实现。 Set Redis set对外提供的功能与list相似是一个列表的功能,特殊之处在于set是能够自动排重的,当你须要存储一个列表数据,又不但愿出现重复数据时,set是一个很好的选择,而且set提供了判断某个成员是否在一个set集合内的重要接口,这个也是list所不能提供的。 Sets 集合的概念就是一堆不重复值的组合。利用Redis提供的Sets数据结构,能够存储一些集合性的数据,好比在微博应用中,能够将一个用户全部的关注人存在一个集合中,将其全部粉丝存在一个集合。Redis还为集合提供了求交集、并集、差集等操做,能够很是方便的实现如共同关注、共同喜爱、二度好友等功能,对上面的全部集合操做,你还能够使用不一样的命令选择将结果返回给客户端仍是存集到一个新的集合中。 实现方式: set 的内部实现是一个 value永远为null的HashMap,实际就是经过计算hash的方式来快速排重的,这也是set能提供判断一个成员是否在集合内的缘由。
Sorted set Redis sorted set的使用场景与set相似,区别是set不是自动有序的,而sorted set能够经过用户额外提供一个优先级(score)的参数来为成员排序,而且是插入有序的,即自动排序。当你须要一个有序的而且不重复的集合列表,那么能够选择sorted set数据结构,好比twitter 的public timeline能够以发表时间做为score来存储,这样获取时就是自动按时间排好序的。 另外还能够用Sorted Sets来作带权重的队列,好比普通消息的score为1,重要消息的score为2,而后工做线程能够选择按score的倒序来获取工做任务。让重要的任务优先执行。 pub/sub Pub/Sub 从字面上理解就是发布(Publish)与订阅(Subscribe),在Redis中,你能够设定对某一个key值进行消息发布及消息订阅,当一个key值上进行了消息发布后,全部订阅它的客户端都会收到相应的消息。这一功能最明显的用法就是用做实时消息系统,好比普通的即时聊天,群聊等功能。
Transactions 谁说NoSQL都不支持事务,虽然Redis的Transactions提供的并非严格的ACID的事务(好比一串用EXEC提交执行的命令,在执行中服务器宕机,那么会有一部分命令执行了,剩下的没执行),可是这个Transactions仍是提供了基本的命令打包执行的功能(在服务器不出问题的状况下,能够保证一连串的命令是顺序在一块儿执行的,中间有会有其它客户端命令插进来执行)。Redis还提供了一个Watch功能,你能够对一个key进行Watch,而后再执行Transactions,在这过程当中,若是这个Watched的值进行了修改,那么这个Transactions会发现并拒绝执行。
3.redis的复制如何实现?redis集群模式如何实现的?redis的key如何寻址?
Redis 使用异步复制。 从 Redis 2.8 开始, 从服务器会以每秒一次的频率向主服务器报告复制流(replication stream)的处理进度。 一个主服务器能够有多个从服务器。 不只主服务器能够有从服务器, 从服务器也能够有本身的从服务器, 多个从服务器之间能够构成一个图状结构。 复制功能不会阻塞主服务器: 即便有一个或多个从服务器正在进行初次同步, 主服务器也能够继续处理命令请求。 复制功能也不会阻塞从服务器: 只要在 redis.conf 文件中进行了相应的设置, 即便从服务器正在进行初次同步, 服务器也能够使用旧版本的数据集来处理命令查询。 不过, 在从服务器删除旧版本数据集并载入新版本数据集的那段时间内, 链接请求会被阻塞。 你还能够配置从服务器, 让它在与主服务器之间的链接断开时, 向客户端发送一个错误。 复制功能能够单纯地用于数据冗余(data redundancy), 也能够经过让多个从服务器处理只读命令请求来提高扩展性(scalability): 好比说, 繁重的 SORT 命令能够交给附属节点去运行。 能够经过复制功能来让主服务器免于执行持久化操做: 只要关闭主服务器的持久化功能, 而后由从服务器去执行持久化操做便可。
doc.redisfans.com/topic/persi… Redis 提供了多种不一样级别的持久化方式: RDB 持久化能够在指定的时间间隔内生成数据集的时间点快照(point-in-time snapshot)。 AOF 持久化记录服务器执行的全部写操做命令,并在服务器启动时,经过从新执行这些命令来还原数据集。 AOF 文件中的命令所有以 Redis 协议的格式来保存,新命令会被追加到文件的末尾。 Redis 还能够在后台对 AOF 文件进行重写(rewrite),使得 AOF 文件的体积不会超出保存数据集状态所需的实际大小。 Redis 还能够同时使用 AOF 持久化和 RDB 持久化。 在这种状况下, 当 Redis 重启时, 它会优先使用 AOF 文件来还原数据集, 由于 AOF 文件保存的数据集一般比 RDB 文件所保存的数据集更完整。 你甚至能够关闭持久化功能,让数据只在服务器运行时存在。 了解 RDB 持久化和 AOF 持久化之间的异同是很是重要的, 如下几个小节将详细地介绍这这两种持久化功能, 并对它们的相同和不一样之处进行说明。
4.redis如何设计分布式锁?zk能够吗?如何实现?哪一个效率更高
获取锁的时候,使用setnx加锁,并使用expire命令为锁添加一个超时时间,超过该时间则自动释放锁,锁的value值为一个随机生成的UUID,经过此在释放锁的时候进行判断。 获取锁的时候还设置一个获取的超时时间,若超过这个时间则放弃获取锁。 释放锁的时候,经过UUID判断是否是该锁,如果该锁,则执行delete进行锁释放。
查看目标Node是否已经建立,已经建立,那么等待锁。 若是未建立,建立一个瞬时Node,表示已经占有锁。 若是建立失败,那么证实锁已经被其余线程占有了,那么一样等待锁。 当释放锁,或者当前Session超时的时候,节点被删除,唤醒以前等待锁的线程去争抢锁。 www.jianshu.com/p/5d12a0101…
5.redis持久化?有什么优缺点?具体底层实现?
6.redis的过时测略有哪些?LRU?写代码? 定时删除 含义:在设置key的过时时间的同时,为该key建立一个定时器,让定时器在key的过时时间来临时,对key进行删除- 优势:保证内存被尽快释放 缺点: 若过时key不少,删除这些key会占用不少的CPU时间,在CPU时间紧张的状况下,CPU不能把全部的时间用来作要紧的事儿,还须要去花时间删除这些key 定时器的建立耗时,若为每个设置过时时间的key建立一个定时器(将会有大量的定时器产生),性能影响严重 没人用 惰性删除 含义:key过时的时候不删除,每次从数据库获取key的时候去检查是否过时,若过时,则删除,返回null。 优势:删除操做只发生在从数据库取出key的时候发生,并且只删除当前key,因此对CPU时间的占用是比较少的,并且此时的删除是已经到了非作不可的地步(若是此时还不删除的话,咱们就会获取到了已通过期的key了) 缺点:若大量的key在超出超时时间后,好久一段时间内,都没有被获取过,那么可能发生内存泄露(无用的垃圾占用了大量的内存) 按期删除 含义:每隔一段时间执行一次删除过时key操做 优势: 经过限制删除操做的时长和频率,来减小删除操做对CPU时间的占用--处理"定时删除"的缺点 按期删除过时key--处理"惰性删除"的缺点 缺点 在内存友好方面,不如"定时删除" 在CPU时间友好方面,不如"惰性删除" 难点 合理设置删除操做的执行时长(每次删除执行多长时间)和执行频率(每隔多长时间作一次删除)(这个要根据服务器运行状况来定了) import java.util.LinkedHashMap; import java.util.Map;
public LRUCache<K, V> extends LinkedHashMap<K, V> { private int cacheSize;
public LRUCache(int cacheSize) { super(16, 0.75, true); this.cacheSize = cacheSize; }
protected boolean removeEldestEntry(Map.Entry<K, V> eldest) { return size() >= cacheSize; } }
1.dubbo的实现过程?注册中心挂了能够继续通讯吗? 服务容器负责启动,加载,运行服务提供者。
2.zk原理?zk均可以作什么?paxos算法知道吗?说一下原理和实现? ZooKeeper数据模型的结构与Unix文件系统很相似,总体上能够看做是一棵树,每一个节点称作一个ZNode。每一个ZNode均可以经过其路径惟一标识,好比上图中第三层的第一个ZNode, 它的路径是/app1/c1。在每一个ZNode上可存储少许数据
整体说来,paxos就是经过两个阶段肯定一个决议:Phase1:肯定谁的编号最高,只有编号最高者才有权利提交proposal;Phase2:编号最高者提交proposal,若是没有其余节点提出更高编号的proposal,则该提案会被顺利经过;不然,整个过程就会重来。你编号高,我比你更高,反复如此,算法永远没法结束,这叫活锁。FLP Impossibility已经证实,在异步通讯中不存在任何一致性算法,活锁即是Paxos没法解决的硬伤。
3.dubbo支持哪些序列化协议?hessian?他的数据结构呢?PB知道吗?为啥PB是效率最高的? dubbo共支持以下几种通讯协议:
dubbo:// rmi:// hessian:// http:// webservice:// thrift:// memcached:// redis://
4.netty?netty能够干啥?NIO BIO AIO都是什么?有什么区别?
5.dubbo的复制均衡和高可用测略有那些?动态代理测略呢?
Dubbo提供了多种均衡策略,缺省为random随机调用 随机,按权重设置随机几率。 轮循,按公约后的权重设置轮循比率。 最少活跃调用数,相同活跃数的随机,活跃数指调用先后计数差。使慢的提供者收到更少请求,由于越慢的提供者的调用先后计数差会越大。 一致性Hash,相同参数的请求老是发到同一提供者。
6.为何要进行系统拆分?拆分不用dubbo能够么?dubbo和thrift有什么区别? thrift其实只是一个跨平台的序列化协议,跟dubbo中使用的hessian2或json等价。
分布式消息队列 1.为何使用消息队列?消息队列有什么有点和缺点?
2.如何保证消息队列的高可用?如何保证消息不被重复消费? 参照rabbitmq ack机制,对消费的数据预存在某个位置,消费端必定要提供消费回馈,否则数据持久保存在那
在数据生产时避免数据丢失的方法: 只要能避免上述两种状况,那么就能够保证消息不会被丢失。 1)就是说在同步模式的时候,确认机制设置为-1,也就是让消息写入leader和全部的副本。 2)还有,在异步模式下,若是消息发出去了,但尚未收到确认的时候,缓冲池满了,在配置文件中设置成不限制阻塞超时的时间,也就说让生产端一直阻塞,这样也能保证数据不会丢失。 在数据消费时,避免数据丢失的方法:若是使用了storm,要开启storm的ackfail机制;若是没有使用storm,确认数据被完成处理以后,再更新offset值。低级API中须要手动控制offset值。
针对消息重复:将消息的惟一标识保存到外部介质中,每次消费时判断是否处理过便可。
3.kafka,activemq,rocketmq,rabbitmq有什么优缺点? blog.csdn.net/kaixuanfeng… rocketmq:顺序消息、消息重复rocketmq不保证(业务端去重)、事务消息 4.如何让你实现一个消息队列,如何进行架构设计?说一下思路 mq 幂等 顺序 延迟
顺序性:保证生产者 - MQServer - 消费者是一对一对一的关系 分布式搜索引擎 1,es的工做过程是如何实现的?如何实现分布式的? www.cnblogs.com/tgzhu/p/609… www.cnblogs.com/licongyu/p/… 路由和分片 分片 文档在索引的时候,须要肯定文档存放到哪一个分片上去。(经过把 _id 做为 routing 来计算 shard) 文档在检索的时候,须要肯定文档处在具体哪一个分片上。(经过把 _id 做为 routing 来计算 shard) 2.es在数据量很大的状况下如何提升查询效率?(10亿) 亿级规模的ES查询优化实战 能用filter就不用query filter拿到相应的doc后不计算score不用排序 query会对符合条件的doc计算score并进行排序 filter的查询速度比query快不少
增长相关cache的配置 indices.cache.filter.size: 30% indices.fielddata.cache.size: 60% index.cache.field.type: soft indices.breaker.fielddata.limit: 70%
优化方案——总结 能用filter就不用query 增长冗余字段将部分range aggregation查询变成terms aggregation 为经常使用字段增长配置,将fielddata的loading设成eager,尽可能多加载到内存 增长集群的缓存资源,把内存尽可能多的用起来 Global ordinals Index warmer 调整aggregation的collect_mode 上SSD 使用bulk请求 而且每一个请求不超过几十M,由于太大会致使内存使用过大 如何提升ES的性能 不要返回较大的结果集
ES是设计成一个搜索引擎的,只擅长返回匹配查询较少文档,若是须要返回很是多的文档须要使用Scroll。
避免稀疏
由于ES是基于Lucene来索引和存储数据的,因此对稠密的数据更有效。Lucene可以有效的肯定文档是经过一个整数的文档id,不管有没有数据都会话费一个字节存储id。稀疏主要影响norms和doc_values,一些能够避免稀疏的推荐:
避免将不相关的数据放到相同的索引中
规范的文档结构
使用相同的字段名来保存一样的数据。
避免类型
不用norms和doc_values在稀疏字段
调整索引速度 使用bulk请求
而且每一个请求不超过几十M,由于太大会致使内存使用过大
使用 multiple workers/threads发送数据到ES
多进程或者线程,若是看到TOO_MANY_REQUESTS (429)和EsRejectedExecutionException则说明ES跟不上索引的速度,当集群的I/O或者CPU饱和就获得了工做者的数量。
增长刷新间隔
index.refresh_interval默认是1s,能够改为30s以减小合并压力。
在加载大量数据时候能够暂时不用refresh和repliccas
index.refresh_interval to -1 and index.number_of_replicas to 0
禁用swapping
禁用swapping
给文件缓存分配内存
缓存是用来缓存I/O操做的,至少用通常的内存来运行ES文件缓存。
使用更快的硬件
使用SSD做为存储设备。 使用本地存储,避免使用NFS或者SMB 注意使用虚拟存储,好比亚马逊的EBS 索引缓冲大小
indices.memory.index_buffer_size一般是JVM的0.1,确保他足够处理至多512MB的索引。
调整搜索速度 给文件系统缓存大内存
至少给可用内存的一半到文件系统缓存。
使用更快的硬件
使用SSD做为存储设备。 使用性能更好的CPU,高并发 使用本地存储,避免使用NFS或者SMB 注意使用虚拟存储,好比亚马逊的EBS 文档建模
避免连接,嵌套会使查询慢几倍,而亲自关系能使查询慢几百倍,因此若是一样的问题能够经过没有连接的非规范回答就能够提高速度。
预索引数据
映射
数值型数据不必定要映射成整形或者长整型
避免scripts
若是实在要使用,就用painless和expressions
强势合并只读索引
www.elastic.co/guide/en/el… 不要强势合并正在写的索引
准备全局顺序
准备文件系统缓存
index.store.preload,若是内存不是很大会使搜索变得缓慢。
调整磁盘使用 禁用不须要的功能
不须要过滤时能够禁用索引“index”:false 若是你不须要text字段的score,能够禁用”norms”:false 若是不须要短语查询能够不索引positions"indexe_options":"freqs" 不用默认的动态字符串匹配
不要使用_all
使用best_compression
使用最小的足够用的数值类型
byte,short,integer,long half_float,float,double
3.es的查询是一个怎么样的过程?底层的lucence介绍一下?到排索引知道吗? es和mongo有什么区别?什么场景下使用? 深分页场景ES性能极差,ES应该主要仍是搜索、以及目前正在增强的用于数据分析。作存储有些深分页查询场景因性能没法使用。 Es更新后即时查询较差,延迟高。mongo在并发条件下也强于es
1,如何设计一个高并发高可用系统? 高并发原则 无状态 拆分 服务化 消息队列 数据异构 缓存银弹 高可用原则: 降级 限流 切流量 可回滚 3业务设计原则 防重设计 幂等设计 流程定义 状态与状态机 后台系统操做可反馈 后台系统审批化 文档注释 备份 2,如何限流?工做中怎么作的?说一下具体实现?
限制总并发数(好比数据库链接池、线程池) 限制瞬时并发数(如nginx的limit_conn模块,用来限制瞬时并发链接数) 限制时间窗口内的平均速率(如Guava的RateLimiter、nginx的limit_req模块,限制每秒的平均速率) 限制远程接口调用速率 限制MQ的消费速率。 能够根据网络链接数、网络流量、CPU或内存负载等来限流
3.缓存如何使用的?缓存使用不当会形成什么后果? blog.csdn.net/u011277123/…
4.如何熔断?熔断框架有哪些?具体实现原理知道吗? 相似现实世界中的“保险丝“,当某个异常条件被触发,直接熔断整个服务,而不是一直等到此服务超时。 熔断的触发条件能够依据不一样的场景有所不一样,好比统计一个时间窗口内失败的调用次数。 NetFlix Hydrix Hystrix为每个依赖服务维护一个线程池(或者信号量),当线程池占满,该依赖服务将会当即拒绝服务而不是排队等待 每一个依赖服务都被隔离开来,Hystrix 会严格控制其对资源的占用,并在任何失效发生时,执行失败回退逻辑。
hystrix语义为“豪猪”,具备自我保护的能力。hystrix的出现即为解决雪崩效应,它经过四个方面的机制来解决这个问题
隔离(线程池隔离和信号量隔离):限制调用分布式服务的资源使用,某一个调用的服务出现问题不会影响其余服务调用。 优雅的降级机制:超时降级、资源不足时(线程或信号量)降级,降级后能够配合降级接口返回托底数据。 融断:当失败率达到阀值自动触发降级(如因网络故障/超时形成的失败率高),熔断器触发的快速失败会进行快速恢复。 缓存:提供了请求缓存、请求合并实现。 支持实时监控、报警、控制(修改配置) (1)线程池隔离模式:使用一个线程池来存储当前的请求,线程池对请求做处理,设置任务返回处理超时时间,堆积的请求堆积入线程池队列。这种方式须要为每一个依赖的服务申请线程池,有必定的资源消耗,好处是能够应对突发流量(流量洪峰来临时,处理不完可将数据存储到线程池队里慢慢处理) (2)信号量隔离模式:使用一个原子计数器(或信号量)来记录当前有多少个线程在运行,请求来先判断计数器的数值,若超过设置的最大线程个数则丢弃改类型的新请求,若不超过则执行计数操做请求来计数器+1,请求返回计数器-1。这种方式是严格的控制线程且当即返回模式,没法应对突发流量(流量洪峰来临时,处理的线程超过数量,其余的请求会直接返回,不继续去请求依赖的服务)
5.如何降级?如何进行系统拆分?如何进行数据库拆分? 降级须要对下层依赖的业务分级,把产生故障的丢了,换一个轻量级的方案,是一种退而求其次的方法。 根据业务场景的不一样,通常采用如下两种模式: 第一种(最经常使用)若是服务失败,则咱们经过fallback进行降级,返回静态值。
第二种采用服务级联的模式,若是第一个服务失败,则调用备用服务,例如失败重试或者访问缓存失败再去取数据库。服务级联的目的则是尽最大努力保证返回数据的成功性,但若是考虑不充分,则有可能致使级联的服务崩溃(好比,缓存失败了,把所有流量打到数据库,瞬间致使数据库挂掉)。所以级联模式,也要慎用,增长了管理的难度。
1,说一下TCP/IP四层? 应用层:应用程序间沟通的层,如简单电子邮件传输(SMTP)、文件传输协议(FTP)、网络远程访问协议(Telnet)等。 传输层:在此层中,它提供了节点间的数据传送服务,如传输控制协议(TCP)、用户数据报协议(UDP)等,TCP和UDP给数据包加入传输数据并把它传输到下一层中,这一层负责传送数据,而且肯定数据已被送达并接收。 互连网络层:负责提供基本的数据封包传送功能,让每一块数据包都可以到达目的主机(但不检查是否被正确接收),如网际协议(IP)。 网络接口层:对实际的网络媒体的管理,定义如何使用实际网络(如Ethernet、Serial Line等)来传送数据。
2.http的工做流程?http1.0 1.1 2.0有哪些区别? 地址解析 如用客户端浏览器请求这个页面:localhost.com:8080/index.htm 从中分解出协议名、主机名、端口、对象路径等部分,对于咱们的这个地址,解析获得的结果以下: 协议名:http 主机名:localhost.com( 在这一步,须要域名系统DNS解析域名localhost.com,得主机的IP地址。) 端口:8080 对象路径:/index.htm 封装http请求数据包 封装成tcp包,创建tcp链接(三次握手) 在HTTP工做开始以前,客户机(Web浏览器)首先要经过网络与服务器创建链接,该链接是经过TCP来完成的 客户端发送请求 服务器响应 服务器关闭tcp链接
长链接 HTTP 1.0须要使用keep-alive参数来告知服务器端要创建一个长链接,而HTTP1.1默认支持长链接。 HTTP是基于TCP/IP协议的,建立一个TCP链接是须要通过三次握手的,有必定的开销,若是每次通信都要从新创建链接的话,对性能有影响。所以最好能维持一个长链接,能够用个长链接来发多个请求。 节约带宽 HTTP 1.1支持只发送header信息(不带任何body信息),若是服务器认为客户端有权限请求服务器,则返回100,不然返回401。客户端若是接受到100,才开始把请求body发送到服务器。 这样当服务器返回401的时候,客户端就能够不用发送请求body了,节约了带宽。 另外HTTP还支持传送内容的一部分。这样当客户端已经有一部分的资源后,只须要跟服务器请求另外的部分资源便可。这是支持文件断点续传的基础。 HOST域 如今能够web server例如tomat,设置虚拟站点是很是常见的,也便是说,web server上的多个虚拟站点能够共享同一个ip和端口。 HTTP1.0是没有host域的,HTTP1.1才支持这个参数。 HTTP1.1 HTTP 2.0主要区别 多路复用 HTTP2.0使用了多路复用的技术,作到同一个链接并发处理多个请求,并且并发请求的数量比HTTP1.1大了好几个数量级。 固然HTTP1.1也能够多创建几个TCP链接,来支持处理更多并发的请求,可是建立TCP链接自己也是有开销的。 TCP链接有一个预热和保护的过程,先检查数据是否传送成功,一旦成功过,则慢慢加大传输速度。所以对应瞬时并发的链接,服务器的响应就会变慢。因此最好能使用一个创建好的链接,而且这个链接能够支持瞬时并发的请求。 关于多路复用,能够参看学习NIO 。 数据压缩 HTTP1.1不支持header数据的压缩,HTTP2.0使用HPACK算法对header的数据进行压缩,这样数据体积小了,在网络上传输就会更快。 服务器推送 意思是说,当咱们对支持HTTP2.0的web server请求数据的时候,服务器会顺便把一些客户端须要的资源一块儿推送到客户端,省得客户端再次建立链接发送请求到服务器端获取。这种方式很是合适加载静态资源。 服务器端推送的这些资源其实存在客户端的某处地方,客户端直接从本地加载这些资源就能够了,不用走网络,速度天然是快不少的。 3.TCP三次握手,4次分手工做流程?画图?为何不是5次或者2次? 4.画一下https的工做流程?如何实现?如何防止被抓包? 客户端发送请求到服务器端 服务器端返回证书和公开密钥,公开密钥做为证书的一部分而存在 客户端验证证书和公开密钥的有效性,若是有效,则生成共享密钥并使用公开密钥加密发送到服务器端 服务器端使用私有密钥解密数据,并使用收到的共享密钥加密数据,发送到客户端 客户端使用共享密钥解密数据 SSL加密创建………
验证消息的确来自微信服务器 经过 timestamp, nonce 以及双方约定好的 token 构成一个签名,可以验证信息是否来自微信。
在这里并不适用,由于api就是由用户调用的。
算法 1,有一个文件,45亿个阿拉伯数字,,如何去重?如何找出最大的那个? 方案1:申请512M的内存(2^32/8=512MB),一个bit位表明一个unsigned int值。读入40亿个数,设置相应的bit位,读入要查询的数,查看相应bit位是否为1,为1表示存在,为0表示不存在。 mapreduce 数据结构 2.二叉树,红黑树
1.class.forname和classloader有什么区别 java中class.forName()和classLoader均可用来对类进行加载。 class.forName()前者除了将类的.class文件加载到jvm中以外,还会对类进行解释,执行类中的static块。 而classLoader只干一件事情,就是将.class文件加载到jvm中,不会执行static中的内容,只有在newInstance才会去执行static块。 Class.forName(name, initialize, loader)带参函数也可控制是否加载static块。而且只有调用了newInstance()方法采用调用构造函数,建立类的对象
2.arraylist,hashmap ArrayList底层以数组实现,容许重复,默认第一次插入元素时建立数组的大小为10,超出限制时会增长50%的容量,每次扩容都底层采用System.arrayCopy()复制到新的数组,初始化时最好能给出数组大小的预估值。
和LinkedList的区别
一、ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。 二、对于随机访问get和set,ArrayList以为优于LinkedList,由于LinkedList要移动指针。 三、对于新增和删除操做add和remove(不是在尾部添加删除),LinkedList比较占优点,由于ArrayList要移动数据。
和Vector的区别 一、Vector和ArrayList几乎是彻底相同的,惟一的区别在于Vector是同步类(synchronized),属于强同步类。所以开销就比ArrayList要大,访问要慢。正常状况下,大多数的Java程序员使用ArrayList而不是Vector,由于同步彻底能够由程序员本身来控制。 二、Vector每次扩容请求其大小的2倍空间,而ArrayList是1.5倍。 三、Vector还有一个子类Stack.
LinkedList以双向链表实现,容许重复。(以下Node的实现)并保留头指针和尾指针。 链表无容量限制,但双向链表自己使用了更多空间,也须要额外的链表指针操做。 按下标访问元素—get(i)/set(i,e) 要悲剧的遍历链表将指针移动到位(若是i>数组大小的一半,会从末尾移起)。 插入、删除元素时修改先后节点的指针便可,但仍是要遍历部分链表的指针才能移动到下标所指的位置,只有在链表两头的操做—add(), addFirst(),removeLast()或用iterator()上的remove()能省掉指针的移动
HashMap 工做原理:经过hash算法,经过put和get存储和获取对象。 存储对象时,咱们将K/V传给put方法时,它调用hashCode计算hash从而获得bucket位置,进一步存储,HashMap会根据当前bucket的占用状况自动调整容量(超过Load Factor则resize为原来的2倍)。若是发生碰撞的时候,Hashmap经过链表将产生碰撞冲突的元素组织起来。若是一个bucket中碰撞冲突的元素超过某个限制(默认是8),则使用红黑树来替换链表,从而提升速度。 获取对象时,咱们将K传给get,它调用hashCode计算hash从而获得bucket位置,并进一步调用equals()方法肯定键值对。
HashMap 包含以下几个构造器: HashMap():构建一个初始容量为 16,负载因子为 0.75 的 HashMap。 ashMap(int initialCapacity):构建一个初始容量为 initialCapacity,负载因子为 0.75 的 HashMap。 HashMap(int initialCapacity, float loadFactor):以指定初始容量、指定的负载因子建立一个 HashMap。 HashMap的基础构造器HashMap(int initialCapacity, float loadFactor)带有两个参数,它们是初始容量initialCapacity和负载因子loadFactor。 负载因子loadFactor衡量的是一个散列表的空间的使用程度,负载因子越大表示散列表的装填程度越高,反之愈小。对于使用链表法的散列表来讲,查找一个元素的平均时间是O(1+a),所以若是负载因子越大,对空间的利用更充分,然然后果是查找效率的下降;若是负载因子过小,那么散列表的数据将过于稀疏,对空间形成严重浪费。
从Java 8开始,HashMap,ConcurrentHashMap和LinkedHashMap在处理频繁冲突时将使用平衡树来代替链表,当同一hash桶中的元素数量超过特定的值便会由链表切换到平衡树,这会将get()方法的性能从O(n)提升到O(logn)。
1.redis线程模型,底层实现,如何实现高并发高可用持久化,redis集群的扩容同步,redis序列化的方式,如何防止穿透 Redis 基于 Reactor 模式开发了本身的网络事件处理器: 这个处理器被称为文件事件处理器(file event handler): 文件事件处理器使用 I/O 多路复用(multiplexing)程序来同时监听多个套接字, 并根据套接字目前执行的任务来为套接字关联不一样的事件处理器。 当被监听的套接字准备好执行链接应答(accept)、读取(read)、写入(write)、关闭(close)等操做时, 与操做相对应的文件事件就会产生, 这时文件事件处理器就会调用套接字以前关联好的事件处理器来处理这些事件。 虽然文件事件处理器以单线程方式运行, 但经过使用 I/O 多路复用程序来监听多个套接字, 文件事件处理器既实现了高性能的网络通讯模型, 又能够很好地与 redis 服务器中其余一样以单线程方式运行的模块进行对接, 这保持了 Redis 内部单线程设计的简单性。
Redis sentinel(哨兵)模块已经被集成在redis2.4+的版本中,主要为 Redis 主从架构(M-S)的系统提供: 监控:系统中master/slave 可用性监控 通知:当被监控的redis实例出问题时,通知应用程序 自动故障转移,M-S角色转换等能力。从一个方面说是提升了redis集群的可用性. Redis Sentinel 是一个分布式系统,你能够在一个系统中运行多个 Sentinel 进程(progress),这些进程使用流言协议(gossip protocols)来接收关于master是否下线的信息,并使用投票协议(agreement protocols)来决定是否执行自动故障迁移,以及选择哪一个从服务器做为新的主服务器。 sentinel的一些设计思路和zookeeper很是相似,事实上,你能够不使用sentinel,而是本身开发一个监控redis的zk客户端也可以完成相应的设计要求。
序列化的目的是将一个实现了Serializable接口的对象转换成一个字节序列,能够。 把该字节序列保存起来(例如:保存在一个文件里),之后能够随时将该字节序列恢复为原来的对象.
增量同步 Redis增量同步主要指Slave完成初始化后开始正常工做时,Master发生的写操做同步到Slave的过程。一般状况下,Master每执行一个写命令就会向Slave发送相同的写命令,而后Slave接收并执行。 全量同步 Redis全量复制通常发生在Slave初始化阶段,这时Slave须要将Master上的全部数据都复制一份。具体步骤以下: 1)从服务器链接主服务器,发送SYNC命令; 2)主服务器接收到SYNC命名后,开始执行BGSAVE命令生成RDB文件并使用缓冲区记录此后执行的全部写命令; 3)主服务器BGSAVE执行完后,向全部从服务器发送快照文件,并在发送期间继续记录被执行的写命令; 4)从服务器收到快照文件后丢弃全部旧数据,载入收到的快照; 5)主服务器快照发送完毕后开始向从服务器发送缓冲区中的写命令; 6)从服务器完成对快照的载入,开始接收命令请求,并执行来自主服务器缓冲区的写命令;
缓存穿透:
认识
缓存穿透是指查询一个必定不存在的数据,因为缓存是不命中时须要从数据库查询,查不到数据则不写入缓存,这将致使这个不存在的数据每次请求都要到数据库去查询,形成缓存穿透。 解决办法:
对全部可能查询的参数以hash形式存储,在控制层先进行校验,不符合则丢弃。还有最多见的则是采用布隆过滤器,将全部可能存在的数据哈希到一个足够大的bitmap中,一个必定不存在的数据会被这个bitmap拦截掉,从而避免了对底层存储系统的查询压力。 也能够采用一个更为简单粗暴的方法,若是一个查询返回的数据为空(无论是数 据不存在,仍是系统故障),咱们仍然把这个空结果进行缓存,但它的过时时间会很短,最长不超过五分钟。 缓存雪崩
认识
若是缓存集中在一段时间内失效,发生大量的缓存穿透,全部的查询都落在数据库上,形成了缓存雪崩。 这个没有完美解决办法,但能够分析用户行为,尽可能让失效时间点均匀分布。大多数系统设计者考虑用加锁或者队列的方式保证缓存的单线程(进程)写,从而避免失效时大量的并发请求落到底层存储系统上。 解决方法
在缓存失效后,经过加锁或者队列来控制读数据库写缓存的线程数量。好比对某个key只容许一个线程查询数据和写缓存,其余线程等待。 能够经过缓存reload机制,预先去更新缓存,再即将发生大并发访问前手动触发加载缓存 不一样的key,设置不一样的过时时间,让缓存失效的时间点尽可能均匀 作二级缓存,或者双缓存策略。A1为原始缓存,A2为拷贝缓存,A1失效时,能够访问A2,A1缓存失效时间设置为短时间,A2设置为长期。
2.mq的原理 如何保证消息的可靠性传输 处理消息丢失和解决消息幂等。 mq消息的延迟和过时失效 本身设计一个消息中间件 可靠性:消息的落地,超时重传和确认 幂等 上半场生成全局惟一ID,业务无关,保证同一条消息只投递一次,由mq保证; 下半场幂等要求有全局惟一的businessid 保证只消费一次,业务惟一,对MQ透明。 mq的延迟 最多见方案启动一个cron定时任务,将48小时未拼分的滴滴订单取出评价为5星。效率低下。 能够设计一个环形队列,1-3600,每一个slot是一个Set,里面有属性表明第几圈扫描到此开始执行任务。 //redis zset 实现 用Map来存储元数据。id做为key,整个消息结构序列化(json/…)以后做为value,放入元消息池中。 将id放入其中(有N个)一个zset有序列表中,以createTime+delay+priority做为score。修改状态为正在延迟中 使用timer实时监控zset有序列表中top 10的数据 。 若是数据score<=当前时间毫秒就取出来,根据topic从新放入一个新的可消费列表(list)中,在zset中删除已经取出来的数据,并修改状态为待消费 客户端获取数据只须要从可消费队列中获取就能够了。而且状态必须为待消费 运行时间须要<=当前时间的 若是不知足 从新放入zset列表中,修改状态为正在延迟。若是知足修改状态为已消费。或者直接删除元数据。
3.dubbo的原理 spi思想 如何进行服务治理 dubbo的服务降级 失败重试 设计本身的RPC框架 blog.csdn.net/chao_19/art… spi: 当服务的提供者,提供了服务接口的一种实现以后,在jar包的META-INF/services/目录里同时建立一个以服务接口命名的文件。该文件里就是实现该服务接口的具体实现类。而当外部程序装配这个模块的时候,就能经过该jar包META-INF/services/里的配置文件找到具体的实现类名,并装载实例化,完成模块的注入。 经过mock的配置,能够很好的实现dubbo服务降级
1.超时设置 DUBBO消费端设置超时时间须要根据业务实际状况来设定, 若是设置的时间过短,一些复杂业务须要很长时间完成,致使在设定的超时时间内没法完成正常的业务处理。 这样消费端达到超时时间,那么dubbo会进行重试机制,不合理的重试在一些特殊的业务场景下可能会引起不少问题,须要合理设置接口超时时间。 好比发送邮件,可能就会发出多份重复邮件,执行注册请求时,就会插入多条重复的注册数据。 (1)合理配置超时和重连的思路 对于核心的服务中心,去除dubbo超时重试机制,并从新评估设置超时时间。 业务处理代码必须放在服务端,客户端只作参数验证和服务调用,不涉及业务流程处理 2.重连机制 dubbo在调用服务不成功时,默认会重试2次。 Dubbo的路由机制,会把超时的请求路由到其余机器上,而不是本机尝试,因此 dubbo的重试机器也能必定程度的保证服务的质量。 可是若是不合理的配置重试次数,当失败时会进行重试屡次,这样在某个时间点出现性能问题,调用方再连续重复调用, 系统请求变为正常值的retries倍,系统压力会大增,容易引发服务雪崩,须要根据业务状况规划好如何进行异常处理,什么时候进行重试。
4.AQS原理 哪些地方用到了AQS/CAS ConcurrentHashMap原理 java线程模型。并发下出现那些问题
5.synchronized如何实现,和lock的区别 synchronized: 在资源竞争不是很激烈的状况下,偶尔会有同步的情形下,synchronized是很合适的。缘由在于,编译程序一般会尽量的进行优化synchronize,另外可读性很是好,无论用没用过5.0多线程包的程序员都能理解。
ReentrantLock: ReentrantLock提供了多样化的同步,好比有时间限制的同步,能够被Interrupt的同步(synchronized的同步是不能Interrupt的)等。在资源竞争不激烈的情形下,性能稍微比synchronized差点点。可是当同步很是激烈的时候,synchronized的性能一会儿能降低好几十倍。而ReentrantLock确还能维持常态。
Atomic: 和上面的相似,不激烈状况下,性能比synchronized略逊,而激烈的时候,也能维持常态。激烈的时候,Atomic的性能会优于ReentrantLock一倍左右。可是其有一个缺点,就是只能同步一个值,一段代码中只能出现一个Atomic的变量,多于一个同步无效。由于他不能在多个Atomic之间同步。 6.mysql主从同步延迟处理 2.MySQL数据库主从同步延迟是怎么产生的。
答:当主库的TPS并发较高时,产生的DDL数量超过slave一个sql线程所能承受的范围,那么延时就产生了,固然还有就是可能与slave的大型query语句产生了锁等待。
3.MySQL数据库主从同步延迟解决方案
答:最简单的减小slave同步延时的方案就是在架构上作优化,尽可能让主库的DDL快速执行。还有就是主库是写,对数据安全性较高,好比sync_binlog=1,innodb_flush_log_at_trx_commit = 1 之类的设置,而slave则不须要这么高的数据安全,彻底能够讲sync_binlog设置为0或者关闭binlog,innodb_flushlog也能够设置为0来提升sql的执行效率。另外就是使用比主库更好的硬件设备做为slave。
4.MySQL数据库主从同步延迟产生的因素。
根据MyBatis的日志显示,程序被加载时 MyBatis从XML中读取出各个SQL语句,而后根据XML指定的MAPPER位置绑定相应的接口 而后MyBatis会在自身内容进行动态代理,将各Mapper接口进行动态实现,因此虽然你没有写任何的具体JDBC代码,但实际上MyBatis已经为你作好了这些事情 而后你在Mapper.XXXXX具体调用的时候,就能够操做数据库了
简单的来讲,XML保存了你的SQL逻辑 MAPPER则起到了沟通程序和SQL之间的相互访问 8.tomcat线程模型 一个或多个Acceptor线程,每一个线程都有本身的Selector,Acceptor只负责accept新的链接,一旦链接创建以后就将链接注册到其余Worker线程中。 多个Worker线程,有时候也叫IO线程,就是专门负责IO读写的。方式实现方式就是有专门的线程负责IO事件监听,这些线程有本身的Selector,一旦监听到有IO读写事件,并非像第一种实现方式那样(本身去执行IO操做),而是将IO操做封装成一个Runnable交给Worker线程池来执行,这种状况每一个链接可能会被多个线程同时操做,相比第一种并发性提升了,可是也可能引来多线程问题,在处理上要更加谨慎些。tomcat的NIO模型就是第二种。 模块化: Connector 组件是 Tomcat 中两个核心组件之一,它的主要任务是负责接收浏览器的发过来的 tcp 链接请求,建立一个 Request 和 Response 对象分别用于和请求端交换数据,而后会产生一个线程来处理这个请求并把产生的 Request 和 Response 对象传给处理这个请求的线程,处理这个请求的线程就是 Container 组件要作的事了. Container 是容器的父接口,全部子容器都必须实现这个接口,Container 容器的设计用的是典型的责任链的设计模式,它有四个子容器组件构成,分别是:Engine、Host、Context、Wrapper,这四个组件不是平行的,而是父子关系,Engine 包含 Host,Host 包含 Context,Context 包含 Wrapper
9.分布式事务的场景和解决方案,redis和zk实现分布式锁 事务必须知足传统事务的特性,即原子性,一致性,分离性和持久性。可是分布式事务处理过程当中,
常看法决方案:
10.TCP三次握手和4次挥手为何要这样作
11.项目中的挑战,怎么解决
12.设计一个高并发/高可用系统 www.cnblogs.com/wangzhongqi… 13.分布式环境下保持redis和mysql的数据一致性 Redis只用做cache,写请求只交给MySQL处理。不然你就要本身去解决一个分布式事务的问题 缓存只作失效,不作更新 高一致性状况下不要用缓存
14.dubbo redis mq里面踩过的坑 dubbo由于超时重试 产生雪崩现象,系统相应缓慢 redis批处理能够用pipeline模式提升效率 总结: 一、缓存穿透:查询一个必然不存在的数据。好比文章表,查询一个不存在的id,每次都会访问DB,若是有人恶意破坏,极可能直接对DB形成影响。 二、缓存失效:若是缓存集中在一段时间内失效,DB的压力凸显。这个没有完美解决办法,但能够分析用户行为,尽可能让失效时间点均匀分布。 当发生大量的缓存穿透,例如对某个失效的缓存的大并发访问就形成了缓存雪崩。
全网惟一一个从0开始帮助Java开发者转作大数据领域的公众号~
大数据技术与架构或者搜索import_bigdata关注~
海量【java和大数据的面试题+视频资料】整理在公众号,关注后能够下载~