互联网面试知识技术总结(javacore、jvm、redis、kafka、zookeeper、mysql、hystrix)-第四章...

<3>Dubbo的负载均衡策略 负载均衡的实现是在客户端实现的,当服务提供方是集群的时候,为了避免大量请求一直落到一个或几个服务提供方机器上,从而使这些机器负载很高,甚至打死,需要做一定的负载均衡策略。Dubbo提供了多种均衡策略,缺省为random,也就是每次随机调用一台服务提供者的机器。 Dubbo提供的负载均衡策略 Random LoadBalance:随机策略。按照概率设置权重,比较均匀,并且可以动态调节提供者的权重。 RoundRobin LoadBalance:轮询策略。轮询,按公约后的权重设置轮询比率。会存在执行比较慢的服务提供者堆积请求的情况,比如一个机器执行的非常慢,但是机器没有挂调用(如果挂了,那么当前机器会从Zookeeper的服务列表删除),当很多新的请求到达该机器后,由于之前的请求还没有处理完毕,会导致新的请求被堆积,久而久之,所有消费者调用这台机器上的请求都被阻塞。 LeastActive LoadBalance:最少活跃调用数。如果每个提供者的活跃数相同,则随机选择一个。在每个服务提供者里面维护者一个活跃数计数器,用来记录当前同时处理请求的个数,也就是并发处理任务的个数。所以如果这个值越小说明当前服务提供者处理的速度很快或者当前机器的负载比较低,所以路由选择时候就选择该活跃度最小的机器。如果一个服务提供者处理速度很慢,由于堆积,那么同时处理的请求就比较多,也就是活跃调用数目越大,这也使得慢的提供者收到更少请求,因为越慢的提供者的活跃度越来越大。 ConsistentHash LoadBalance:一致性Hash策略。一致性Hash,可以保证相同参数的请求总是发到同一提供者,当某一台提供者挂了时,原本发往该提供者的请求,基于虚拟节点,平摊到其他提供者,不会引起剧烈变动

简单总结:常见负载均衡策略有(权重)轮询,随机,最小连接数,一致性hash等等 参考:www.cnblogs.com/xhj123/p/90…

<4>Dubbo的核心角色 Provider: 暴露服务的服务提供方。 Consumer: 调用远程服务的服务消费方。 Registry: 服务注册与发现的注册中心。 Monitor: 统计服务的调用次调和调用时间的监控中心。

调用关系说明: 服务容器负责启动,加载,运行服务提供者。 服务提供者在启动时,向注册中心注册自己提供的服务。 服务消费者在启动时,向注册中心订阅自己所需的服务。 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。 <5>Dubbo支持的协议

dubbo:Dubbo缺省协议是dubbo协议,采用单一长连接和NIO异步通讯,适合于小数据量大并发的服务调用,以及服务消费者机器数远大于服务提供者机器数的情况。 反之,Dubbo 缺省协议不适合传送大数据量的服务,比如传文件,传视频等,除非请求量很低。 rmi:RMI协议采用阻塞式(同步)短连接和JDK标准序列化方式。适用范围:传入传出参数数据包大小混合,消费者与提供者个数差不多,可传文件。 hessian:Hessian底层采用Http通讯(同步),采用Servlet暴露服务。适用于传入传出参数数据包较大,提供者比消费者个数多,提供者压力较大,可传文件。 dubbo还支持的其他协议有:http, webservice, thrift, memcached, redis

<6>如果Dubbo的服务端未启动,消费端能起来吗? <dubbo:reference id="" interface="" /> 备注:其中reference的check默认=true,启动时会检查引用的服务是否已存在,不存在时报错,因此默认是起不来

<7>集群容错策略 正常情况下,当我们进行系统设计时候,不仅要考虑正常逻辑下代码该如何走,还要考虑异常情况下代码逻辑应该怎么走。当服务消费方调用服务提供方的服务出现错误时候,Dubbo提供了多种容错方案,缺省模式为failover,也就是失败重试。 Dubbo提供的集群容错模式: Failover Cluster:失败重试 当服务消费方调用服务提供者失败后自动切换到其他服务提供者服务器进行重试。这通常用于读操作或者具有幂等的写操作,需要注意的是重试会带来更长延迟。可通过 retries="2" 来设置重试次数(不含第一次)。 接口级别配置重试次数方法 <dubbo:reference retries="2" /> ,如上配置当服务消费方调用服务失败后,会再重试两次,也就是说最多会做三次调用,这里的配置对该接口的所有方法生效。当然你也可以针对某个方法配置重试次数。 Failfast Cluster:快速失败 当服务消费方调用服务提供者失败后,立即报错,也就是只调用一次。通常这种模式用于非幂等性的写操作。 Failsafe Cluster:失败安全 当服务消费者调用服务出现异常时,直接忽略异常。这种模式通常用于写入审计日志等操作。 Failback Cluster:失败自动恢复 当服务消费端用服务出现异常后,在后台记录失败的请求,并按照一定的策略后期再进行重试。这种模式通常用于消息通知操作。 Forking Cluster:并行调用 当消费方调用一个接口方法后,Dubbo Client会并行调用多个服务提供者的服务,只要一个成功即返回。这种模式通常用于实时性要求较高的读操作,但需要浪费更多服务资源。可通过 forks="2" 来设置最大并行数。 Broadcast Cluster:广播调用 当消费者调用一个接口方法后,Dubbo Client会逐个调用所有服务提供者,任意一台调用异常则这次调用就标志失败。这种模式通常用于通知所有提供者更新缓存或日志等本地资源信息。 如上,Dubbo本身提供了丰富的集群容错模式,但是如果您有定制化需求,可以根据Dubbo提供的扩展接口Cluster进行定制。在后面的消费方启动流程章节会讲解何时/如何使用的集群容错。

Dubbo面试题:www.cnblogs.com/shan1393/p/…

50,Redis到底是多线程还是单线程?线程安全吗 redis是单线程,线程安全 redis可以能够快速执行的原因: (1) 绝大部分请求是纯粹的内存操作(非常快速),因此瓶颈在io (2) 采用单线程,避免了不必要的上下文切换和竞争条件 (3) 非阻塞IO - IO多路复用 redis内部实现采用epoll,采用了epoll+自己实现的简单的事件框架。epoll中的读、写、关闭、连接都转化成了事件,然后利用epoll的多路复用特性,绝不在io上浪费一点时间

51,数据库常见引擎区别

InnoDB(b+树,聚簇索引):支持事务处理,支持外键,支持崩溃修复能力和并发控制。如果需要对事务的完整性要求比较高(比如银行),要求实现并发控制(比如售票),那选择InnoDB有很大的优势。如果需要频繁的更新、删除操作的数据库,也可以选择InnoDB,因为支持事务的提交(commit)和回滚(rollback)(用于事务处理应用程序,具有众多特性,包括ACID事务支持。(提供行级锁))

MyISAM(b+树,非聚簇索引):插入数据快,空间和内存使用比较低。如果表主要是用于插入新记录和读出记录,那么选择MyISAM能实现处理高效率。如果应用的完整性、并发性要求比较低,也可以使用(MyISAM类型不支持事务处理等高级处理,因此也不支持数据的回滚修复)。

MEMORY(hash结构):所有的数据都在内存中,数据的处理速度快,但是安全性不高。如果需要很快的读写速度,对数据的安全性要求较低,可以选择MEMOEY。它对表的大小有要求,不能建立太大的表。所以,这类数据库只使用在相对较小的数据库表。

52,mysql数据库引擎的对应的索引数据结构

53,b树和b+树的比较,blog.csdn.net/z_ryan/arti… 1,在范围查询方面,B+树的优势更加明显,B树的范围查找需要不断依赖中序遍历。首先二分查找到范围下限,在不断通过中序遍历,知道查找到范围的上限即可。整个过程比较耗时,而B+树的范围查找则简单了许多。首先通过二分查找,找到范围下限,然后同过叶子结点的链表顺序遍历,直至找到上限即可,整个过程简单许多,效率也比较高。(b+树的数据都分布在子节点上)

54,常见二叉树 1,二叉查找树,它保证所有节点的左子树都小于该节点,所有节点的右子树都大于该节点。就可以通过大小比较关系来进行快速的检索,在一棵满二叉平衡树的情况下,检索的效率可以达到logn(类似二分检索),然后插入和删除的效率也是稳定的logn

普通二叉查找树的一些问题:二叉搜索树是个很好的数据结构,可以快速地找到一个给定关键字的数据项,并且可以快速地插入和删除数据项。但是二叉搜索树有个很麻烦的问题,如果树中插入的是随机数据,则执行效果很好,但如果插入的是有序或者逆序的数据,那么二叉搜索树的执行速度就变得很慢。因为当插入数值有序时,二叉树就是非平衡的了,排在一条线上,其实就退化成了一个链表……它的快速查找、插入和删除指定数据项的能力就丧失了(blog.csdn.net/eson_15/art…

2,AVL树不仅是一颗二叉查找树,它还有其他的性质。如果我们按照一般的二叉查找树的插入方式可能会破坏AVL树的平衡性。同理,在删除的时候也有可能会破坏树的平衡性,所以我们要做一些特殊的处理,包括:单旋转和双旋转 参考:www.cnblogs.com/zhuwbox/p/3… 3,红黑树:www.cnblogs.com/chenssy/p/3…

红黑树的特征: 1.每个节点不是红色就是黑色的; 2.根节点总是黑色的; 3.如果节点是红色的,则它的子节点必须是黑色的(反之不一定); 4.从根节点到叶节点或空子节点的每条路径,必须包含相同数目的黑色节点(即相同的黑色高度)。

使用场景:一般用于内存空间的数据排序,处理的数据量比较小(避免树的深度变的很深,导致查找深度变大),大数据排序尽量使用b+树

4,红黑树和AVL树的比较(www.cnblogs.com/aspirant/p/…

  1. 红黑树并不追求“完全平衡”——它只要求部分地达到平衡要求,降低了对旋转的要求,从而提高了性能。 红黑树能够以O(log2 n) 的时间复杂度进行搜索、插入、删除操作。此外,由于它的设计,任何不平衡都会在三次旋转之内解决。当然,还有一些更好的,但实现起来更复杂的数据结构,能够做到一步旋转之内达到平衡,但红黑树能够给我们一个比较“便宜”的解决方案。红黑树的算法时间复杂度和AVL相同,但统计性能比AVL树更高。 当然,红黑树并不适应所有应用树的领域。如果数据基本上是静态的,那么让他们待在他们能够插入,并且不影响平衡的地方会具有更好的性能。如果数据完全是静态的,做一个哈希表,性能可能会更好一些。 红黑树是一个更高效的检索二叉树,因此常常用来实现关联数组。典型地,JDK 提供的集合类 TreeMap 本身就是一个红黑树的实现

55,为什么Mysql用B+树做索引而不用B-树或红黑树(blog.csdn.net/xiedelong/a… B+树只有叶节点存放数据,其余节点用来索引,而B-树是每个索引节点都会有Data域。所以从Mysql(Inoodb)的角度来看,B+树是用来充当索引的,一般来说索引非常大,尤其是关系性数据库这种数据量大的索引能达到亿级别,所以为了减少内存的占用,索引也会被存储在磁盘上。 那么Mysql如何衡量查询效率呢?– 磁盘IO次数。 B-树/B+树 的特点就是每层节点数目非常多,层数很少,目的就是为了就少磁盘IO次数,但是B-树的每个节点都有data域(指针),这无疑增大了节点大小,说白了增加了磁盘IO次数(磁盘IO一次读出的数据量大小是固定的,单个数据变大,每次读出的就少,IO次数增多,一次IO多耗时),而B+树除了叶子节点其它节点并不存储数据,节点小,磁盘IO次数就少。这是优点之一。 另一个优点是: B+树所有的Data域在叶子节点,一般来说都会进行一个优化,就是将所有的叶子节点用指针串起来。这样遍历叶子节点就能获得全部数据,这样就能进行区间访问啦。在数据库中基于范围的查询是非常频繁的,而B树不支持这样的遍历操作。

B树相对于红黑树的区别 AVL 数和红黑树基本都是存储在内存中才会使用的数据结构。在大规模数据存储的时候,红黑树往往出现由于树的深度过大而造成磁盘IO读写过于频繁,进而导致效率低下的情况。为什么会出现这样的情况,我们知道要获取磁盘上数据,必须先通过磁盘移动臂移动到数据所在的柱面,然后找到指定盘面,接着旋转盘面找到数据所在的磁道,最后对数据进行读写。磁盘IO代价主要花费在查找所需的柱面上,树的深度过大会造成磁盘IO频繁读写。根据磁盘查找存取的次数往往由树的高度所决定,所以,只要我们通过某种较好的树结构减少树的结构尽量减少树的高度,B树可以有多个子女,从几十到上千,可以降低树的高度。

因为B树是平衡树,每个节点到叶子节点的高度都是相同的,这样可以保证B树的查询是稳定的

数据库系统的设计者巧妙利用了磁盘预读原理,将一个节点的大小设为等于一个页,这样每个节点只需要一次I/O就可以完全载入。为了达到这个目的,在实际实现B-Tree还需要使用如下技巧:每次新建节点时,直接申请一个页的空间,这样就保证一个节点物理上也存储在一个页里,加之计算机存储分配都是按页对齐的,就实现了一个node只需一次I/O。

红黑树和平衡二叉树区别如下: 1、红黑树放弃了追求完全平衡,追求大致平衡,在与平衡二叉树的时间复杂度相差不大的情况下,保证每次插入最多只需要三次旋转就能达到平衡,实现起来也更为简单。 2、平衡二叉树追求绝对平衡,条件比较苛刻,实现起来比较麻烦,每次插入新节点之后需要旋转的次数不能预知。 3,红黑树的查询性能略微逊色于AVL树,因为其比AVL树会稍微不平衡最多一层,也就是说红黑树的查询性能只比相同内容的AVL树最多多一次比较,但是,红黑树在插入和删除上优于AVL树,AVL树每次插入删除会进行大量的平衡度计算,而红黑树为了维持红黑性质所做的红黑变换和旋转的开销,相较于AVL树为了维持平衡的开销要小得多 4,红黑树的关键性质: 从根到叶子的最长的可能路径不多于(<=)最短的可能路径的两倍长。结果是这个树大致上是平衡的。因为操作比如插入、删除和查找某个值的最坏情况时间都要求与树的高度成比例,这个在高度上的理论上限允许红黑树在最坏情况下都是高效的,而不同于普通的二叉查找树 参考:www.jianshu.com/p/37436ed14…

总结:实际应用中,若搜索的次数远远大于插入和删除,那么选择AVL,如果搜索,插入删除次数几乎差不多,应该选择RB(red black tree)

红黑树往往出现由于树的深度过大而造成磁盘IO读写过于频繁,进而导致效率低下的情况在数据较小,可以完全放到内存中时,红黑树的时间复杂度比B树低。 如linux中进程的调度用的是红黑树,反之数据量较大,外存中占主要部分时,B树因其读磁盘次数少,而具有更快的速度。

补充: 1,由于b+树的子节点(节点结构是数组,为了二分查找提交效率)存储了所有的数据(并且各个子节点的数据是有指针关联形成的链表),因此只需要第一次递归查询就可以确定查找的起始位置,再遍历子节点就可以获取到指定范围的数据了 2,b+树和b树都是多叉树,因此可以减少因为文件过大,导致树的深度越来越深(广度换深度)。 3,AVL数和红黑树基本都是存储在内存中才会使用的数据结构(比如hashMap),整体存储的数据量少,查找数据量小,要求的性能更高。

56,hashmap,为什么用红黑树?链表(长度大于8)升级为红黑树之后,查找效率更高(二分查找),那为什么不用普通二叉查找树?红黑树本身就是二叉查找树,红黑树自身保持平衡,避免树变成了单链表,导致深度变大,查找性能降低。为什么不用b树?节点的插入效率没有红黑树高(红黑树不需要保持完全平衡,翻转次数较少,b树需要保持完全平衡,翻转次数比较多,导致耗时较长), 为什么不用b+树?节点的插入效率没有红黑树高,数据占用的空间比较大(子节点存储所有的数据),不利于在内存中做排序。 57,跳跃表:被问到如何让链表的元素查询接近线性时间,其实类似于二叉查找树,时间复杂度是log(n)

58,二分查找(递归非递归),字符串倒序,链表倒序,链表交叉(减除多余步长,同时开始遍历)

59,mysql的聚簇索引和非聚簇索引的区别,聚簇索引(innodb)对应的b+树的子节点存储了主键索引和其它数据域(辅助索引和非索引数据),非聚簇索引对应的b+树的子节点存储了主键索引和辅助索引,对应的数据是另外存储的,非聚簇索引比聚簇索引多了一次读取数据的IO操作,所以查找性能上会差(blog.csdn.net/qq_27607965…

60,mysql的mvcc(多版本控制器) 阿里数据库内核'2017/12'月报中对MVCC的解释是: 多版本控制: 指的是一种提高并发的技术。最早的数据库系统,只有读读之间可以并发,读写,写读,写写都要阻塞。引入多版本之后,只有写写之间相互阻塞,其他三种操作都可以并行,这样大幅度提高了InnoDB的并发度。在内部实现中,与Postgres在数据行上实现多版本不同,InnoDB是在undolog中实现的,通过undolog可以找回数据的历史版本。找回的数据历史版本可以提供给用户读(按照隔离级别的定义,有些读请求只能看到比较老的数据版本),也可以在回滚的时候覆盖数据页上的数据。在InnoDB内部中,会记录一个全局的活跃读写事务数组,其主要用来判断事务的可见性。

61,mysql,丢失更新,脏读,幻读,不可重复读,幻读(www.jianshu.com/p/d8bc0a843…

丢失更新:由于事务A与事务B互相不知道对方的存在,导致更新不一致,解决方案:乐观锁的方式,执行修改时,加上先前获取的数据作为判断条件。 脏读:mysql中一个事务读取了另一个未提交的并行事务写的数据(可能被回滚),那这个读取就是脏读。解决方案:一个事务只能读取另一个事务已经提交的数据。 不可重复读:即不能多次重复去读,因为读出来的结果不一样,因此认为存在不可重复读的问题。解决方案:一个事务只能读取另一个事务已经提交的数据,这就会出现不可重复读的问题。 幻读:事务A一开始查询没有数据,但是插入记录失败,提示主键冲突,这种查询明明没有,插入却提示已经存在的现象,叫做幻读。解决方案:Repeatable read及以上级别通过间隙锁来防止幻读的出现,即锁定特定数据的前后间隙让数据无法被插入

小结:不可重复读的和幻读很容易混淆,不可重复读侧重于修改,幻读侧重于新增或删除。解决不可重复读的问题只需锁住满足条件的行,解决幻读需要锁表

62,mysql的事务隔离级别 事务隔离级别 脏读 不可重复读 幻读 读未提交(read-uncommitted) 是 是 是 读已提交(read-committed) 否 是 是 可重复读(repeatable-read) 否 否 是 串行化(serializable) 否 否 否

serializable级别是最高的 mysql默认的事务隔离级别为repeatable-read

63,mysql的mvcc如何解决幻读? 参考乐观锁,每开启一个事务,都获取一个版本号,后续的操作根据版本号去对比,通过版本号控制是否正常操作 InnoDB的MVCC,是通过在每行记录后面保存两个隐藏的列来实现的。这两个列,一个保存了行的创建时间,一个保存行的过期时间(或删除时间)。当然存储的并不是实际的时间值,而是系统版本号(systemversionnumber)。每开始一个新的事务,系统版本号都会自动递增。事务开始时刻的系统版本号会作为事务的版本号,用来和查询到的每行记录的版本号进行比较。

举例: 此时books表中有5条数据,版本号为1 事务A,系统版本号2:select * from books;因为1<=2所以此时会读取5条数据。 事务B,系统版本号3:insert into books ...,插入一条数据,新插入的数据版本号为3,而其他的数据的版本号仍然是2,插入完成之后commit,事务结束。 事务A,系统版本号2:再次select * from books;只能读取<=2的数据,事务B新插入的那条数据版本号为3,因此读不出来,解决了幻读的问题。

64,mysql四大特性 1.原子性 2.一致性 3.隔离性 4.持久性

65,mysql 七种传播行为:

1.PROPAGATION_REQUIRED:(支持事务)如果当前没有事务,就创建一个新事务,如果当前存在事务,就加入该事务,该设置是最常用的设置。 2.PROPAGATION_SUPPORTS:(支持事务)支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就以非事务执行。 3.PROPAGATION_MANDATORY:(支持事务)支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就抛出异常。 4.PROPAGATION_REQUIRES_NEW:(支持事务)创建新事务,无论当前存不存在事务,都创建新事务。 5.PROPAGATION_NOT_SUPPORTED:(不支持事务)以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。 6.PROPAGATION_NEVER:(不支持事务)以非事务方式执行,如果当前存在事务,则抛出异常。 7.PROPAGATION_NESTED:(不支持事务)如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作

事务传播特性例子讲解:

//ServiveA
@Transactional (propagation = Propagation.REQUIRED )
public void dealA(){
Article a = new Article();
a.setTitlename("1");
this.sql.insert("com.faj.dao.ArticleMapper.insert",a);//插入

serviceB.dealB();//调用另一个Service方法  
复制代码

}

//ServiceB
@Transactional (propagation = Propagation.REQUIRED )
public void dealB(){
Article a = new Article();
a.setTitlename("3");
this.sqlSession.insert("com.faj.dao.ArticleMapper.insert",a);
throw new ApplicationException();
//ApplicationException是一个继承RunTimeExcepiotn的异常处理类
}

REQUIRED是重可重入级别的,dealA调用了dealB,因为事务的传播行为是PROPAGATION_REQUIRED(如果有事务,那么加入事务,没有的话新创建一个),dealB加入到dealA的事务中,也就是两个方法共享一个事务,因为是共享事务,所以两条插入语句都会回滚。 参考:angelbill3.iteye.com/blog/193847…

66,mysql关联插叙方式 1,内查询(类似普通的联合查询),返回两个表的交集,例子: select * from a_table a inner join b_table b on a.a_id = b.b_id; 2,左连接(左外连接),left join 是left outer join的简写,它的全称是左外连接,是外连接中的一种。左(外)连接,左表(a_table)的记录将会全部表示出来,而右表(b_table)只会显示符合搜索条件的记录。右表记录不足的地方均为NULL。例子:select * from a_table a left join b_table bon a.a_id = b.b_id; 3,右连接(右外连接),right join是right outer join的简写,它的全称是右外连接,是外连接中的一种。与左(外)连接相反,右(外)连接,左表(a_table)只会显示符合搜索条件的记录,而右表(b_table)的记录将会全部表示出来。左表记录不足的地方均为NULL。例子:select * from a_table a right outer join b_table b on a.a_id = b.b_id;

67,连接查询(join on) 为什么比子查询(in),联合查询(from table1,table2)效率高? 表连接的时候都要先形成一张笛卡尔积表,如果两张表的数据量都比较大的话,那样就会占用很大的内存空间这显然是不合理的。所以,我们在进行表连接查询的时候一般都会使用JOIN xxx ON xxx的语法,ON语句的执行是在JOIN语句之前的,也就是说两张表数据行之间进行匹配的时候,会先判断数据行是否符合ON语句后面的条件,再决定是否JOIN,此时生成的笛卡尔积临时表比较小。避免使用 FROM table1,table2 WHERE xxx 的语法,因为会在内存中先生成一张数据量比较大的笛卡尔积表,增加了内存的开销。in子查询也是先生成临时表,再做一次笛卡尔积生成新临时表,导致效率比较低。

68,mysql索引类别 1.普通索引 2.唯一索引 3.主键索引 4.组合索引 5.全文索引(目前只有MyISAM引擎支持,对搜索引擎稍微有点了解的同学,肯定知道分词这个概念,FULLTEXT索引也是按照分词原理建立索引的。西文中,大部分为字母文字,分词可以很方便的按照空格进行分割。但很明显,中文不能按照这种方式进行分词。那又怎么办呢?这个向大家介绍一个Mysql的中文分词插件Mysqlcft)

69,什么是覆盖索引 select的数据列只用从索引中就能够取得,不必从数据表中读取,换句话说查询列要被所使用的索引覆盖。(通过explain命令可以测试是否被索引命中“返回using index”)

70,为什么选用自增量作为主键索引 mysql的innodb和myisam是mysql最常见的两种数据库引擎,底层实现都是使用了b+树,b+树的叶子节点都是存储了有序片段数据,如果顺序自增键插入子节点更加高效,避免随机插入频繁导致节点的裂变。(非单调的主键会造成在插入新记录时数据文件为了维持B+Tree的特性而频繁的分裂调整,十分低效,而使用自增字段作为主键则是一个很好的选择)

71,mysql死锁的条件及应对措施 原因:两个事务执行逻辑,各自的内部逻辑相互等待另外一个事务释放锁。

例子: 事务1 START TRANSACTION; UPDATE StockPrice SET close = 45.50 WHERE stock_id = 4 and date = '2002-05-01';#(获取行锁) UPDATE StockPrice SET close = 19.80 WHERE stock_id = 3 and date = '2002-05-02';#(获取行锁) COMMIT;#释放事务里面的两个行锁 事务2 START TRANSACTION; UPDATE StockPrice SET high = 20.12 WHERE stock_id = 3 and date = '2002-05-02';#(获取行锁) UPDATE StockPrice SET close = 41.50 WHERE stock_id = 4 and date = '2002-05-01';#(获取行锁) COMMIT;#释放事务里面的两个行锁

解决办法: 1,添加超时策略,超时回滚事务,避免锁被持续竞争 2,以固定的顺序访问你的表和行。则事务形成良好定义的查询并且没有死锁。 参考:blog.csdn.net/wwd0501/art…

72,谈谈sql查询优化 1,要利用索引查询。 2,尽量利用主键查询。 3,连接查询代(join on)替子查询(in)和联合查询(from t1,t2),避免在内存从形成巨大的笛卡尔积。 4,批量扫表时,每次查询应该使用上次查询返回的主键id作为查询条件,提高查询效率。

73,mysql常见的集群方案(blog.51cto.com/mingongge/2… a,一主多从 将master数据库中的DDL和DML操作通过二进制日志(BINLOG)传输到slave数据库上,然后将这些日志重新执行(重做);从而使得slave数据库的数据与master数据库保持一致。 主从复制基本原理: 从库生成两个线程,一个I/O线程,一个SQL线程;i/o线程去请求主库 的binlog,并将得到的binlog日志写到relay log(中继日志) 文件中;主库会生成一个 log dump 线程,用来给从库 i/o线程传binlog;SQL线 程,会读取relay log文件中的日志,并解析成具体操作,来实现主从的操作一致,而最终数据一致。 参考:blog.51cto.com/13266497/21…

mysql主从复制存在的问题: 1,主库宕机后,数据可能丢失 2,从库只有一个sql Thread,主库写压力大,复制很可能延时

解决方法: 半同步复制---解决数据丢失的问题 异步复制----解决从库复制延迟的问题 全同步复制:当主库提交事务之后,所有的从库节点必须收到、APPLY并且提交这些事务,然后主库线程才能继续做后续操作。但缺点是,主库完成一个事务的时间会被拉长,性能降低。 异步复制,主库将事务 Binlog 事件写入到 Binlog 文件中,此时主库只会通知一下 Dump 线程发送这些新的 Binlog,然后主库就会继续处理提交操作,而此时不会保证这些 Binlog 传到任何一个从库节点上。 半同步复制:一个事务在主服务器上执行完成后,必须至少确保至少在一台从服务器上执行完成后,事务才算提交成功。 主库写入一个事务commit提交并执行完之后,并不直接将请求反馈给前端应用用户,而是等待从库也接收到binlog日志并成功写入中继日志后,主库才返回commit操作成功给客户端。半同步复制保障了事物执行后,至少有两份日志记录,一份在主库的binlog上 ,另一份至少在从库的中继日志Relay log上,这样就极大的保证了数据的一致性

Mysql的master和slave切换,心跳检测程序检测到master挂掉,slave之间会检测binlog的最新操作记录,确定谁是最新的就成为master,再回写到配置中心(类似zk的实现lion),并且通知业务方主库更新。

74,mysql三大范式(baijiahao.baidu.com/s?id=159195… 第一范式:所有属性都不能在分解为更基本的数据单位时,简记为1NF。满足第一范式是关系数据库的最低要求。 第二范式:每个非主键属性完全依赖于主键属性,数据存在冗余,或者部分数据无法入表,如:学生表和课程表不应该整合在一块,课程信息可能冗余,也可以插不进去。 第三范式:数据不传递依赖关系(属性都跟主键有直接关系而不是间接关系),数据存在冗余,如:(学号,姓名,年龄,性别,所在院校,院校地址,院校电话)可拆成(学号,姓名,年龄,性别,所在院校)和(所在院校,院校地址,院校电话)。 75,mysql索引最左原则 针对类似建立的索引是联合索引(a,b,c),如果查询使用a,ab,abc,ac都会调用索引查询

76,mysql组合索引的b+树结构(www.2cto.com/database/20… 联合索引(col1, col2,col3)也是一棵B+Tree,其非叶子节点存储的是第一个关键字的索引(第一列),而叶节点存储的则是三个关键字col1、col2、col3三个关键字的数据,且按照col1、col2、col3的顺序进行排序,只有这样做才符合最左原则的查询

77,redis有哪些数据结构 string(普通的k-v存储), hash,常见的对象存储,如存一个shopDTO list(底层实现是链表,存储重复的数据),场景:好友最新消息,基于list可以实现队列或者栈,头插或者尾插 set(HashMap实现的,Set只用了HashMap的key列来存储对象,不允许有重复数据),集合有取交集、并集、差集等操作,因此可以求共同好友、共同兴趣、分类标签等。 zset(有序集合,内部使用HashMap和跳跃表(SkipList)来保证数据的存储和有序),

79,redis常见面试题:blog.csdn.net/u010682330/…

80,Redis集群最大节点个数是多少? 16384个 81,Redis相比memcached有哪些优势? memcached所有的值均是简单的字符串,redis作为其替代者,支持更为丰富的数据类型 redis可以持久化其数据 备注:  Memcached是多线程,非阻塞IO复用的网络模型,分为监听主线程和worker子线程,监听线程监听网络连接,接受请求后,将连接描述字pipe 传递给worker线程,进行读写IO, 网络层使用libevent封装的事件库,多线程模型可以发挥多核作用

Redis使用单线程的IO复用模型,自己封装了一个简单的AeEvent事件处理框架,主要实现了epoll、kqueue和select,对于单纯只有IO操作来说,单线程可以将速度优势发挥到最大,但是Redis也提供了一些简单的计算功能,比如排序、聚合等,对于这些操作,单线程模型实际会严重影响整体吞吐量,CPU计算过程中,整个IO调度都是被阻塞住的 参考:www.2cto.com/database/20…

82,redis何时触发淘汰数据的动作

一个客户端执行指令,导致数据的增加时。 Redis检测到内存的使用已经达到上限。 Redis自身执行指令时

补充:Redis为了避免反复触发淘汰策略,每次会淘汰掉一批数据。

Redis的内存淘汰策略 Redis的内存淘汰策略是指在Redis的用于缓存的内存不足时,怎么处理需要新写入且需要申请额外空间的数据。

83,redis内存淘汰策略(LRU算法) allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的key。 allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个key。 volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的key。 volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个key。 volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的key优先移除。 noeviction:当内存不足以容纳新写入数据时,新写入操作会报错。

Redis中同时使用了惰性过期(对cpu友好,对内存不友好,长期占用内存才能,使用的时候检查有效期),定期过期(集中使用cpu),过时立马删除(异步线程扫描所有数据),底层是有一个字典结构,在惰性删除时,会扫描检查key是否超时。

链接:www.jianshu.com/p/8aa619933…

84,MySQL里有2000w数据,redis中只存20w的数据,如何保证redis中的数据都是热点数据? redis内存数据集大小上升到一定大小的时候,就会施行数据淘汰策略(计算一下 20W 数据大约占用的内存,然后设置一下 Redis 内存限制即可)

85,Redis集群会有写操作丢失吗?为什么? Redis并不能保证数据的强一致性,这意味这在实际中集群在特定的条件下可能会丢失写操作。

86、Redis集群之间是如何复制的? 异步复制

87,Reactor模式,参考:www.cnblogs.com/doit8791/p/…

88,Lucene倒排索引原理

倒排索引(hash表) 倒排索引在全文检索(如单词检索)环境中的利器,而mysql的b+树对于全文检索非常困难,因此mysql的b+树索引是基于数值排序(如主键索引)。

简述正排索引和倒排索引 举例:如有两个文档,doc1,doc2,里面有很多单词,我们查找单词”hello“出现的频次

正排索引实现:doc1->每个单词->词频 检索过程:先逐个遍历文档,再找单词词频,如果是海量文件,查找效率很慢(需要遍历所有的文件)

倒排索引实现:每个单词->{(doc1,10),(doc2,13),...(文档id,频次)} 检索过程:先找单词,再找文档,再找单词词频,对于海量文件,查找效率非常高

备注:正排索引是文档id到单词,而倒排索引是单词到文档id

参考:www.cnblogs.com/zlslch/p/64…

88,Lucene倒排索引压缩算法

为了减小索引文件的大小,Lucene对索引还使用了压缩技术。 首先,对词典文件中的关键词进行了压缩,关键词压缩为<前缀长度,后缀>,例如:当前词为“阿拉伯语”,上一个词为“阿拉伯”,那么“阿拉伯语”压缩为<3,语>。 其次大量用到的是对数字的压缩,数字只保存与上一个值的差值(这样可以减小数字的长度,进而减少保存该数字需要的字节数)。例如当前文章号是16389(不压缩要用3个字节保存),上一文章号是16382,压缩后保存7(只用一个字节)。

www.cnblogs.com/ygj0930/art…

89,Lucene&Solr&ElasticSearch <1>Elasticsearch是一个实时的分布式搜索和分析引擎。可以快速处理大规模数据。可以用于全文搜索、结构化搜索和分析   利用zk实现分布式实时文件存储,并将每一个字段都编入索引,使其可以被搜索;   实时分析的分布式搜索引擎;   可以扩展到上百台服务器,处理PB级别的结构化或非结构化数据

<2>Solr是Apache Lucene项目的开源企业搜索平台。主要功能包括全文检索、命中标示、分面搜索、动态聚类、数据库集成,以及富文本的处理。是高度可扩展的,并提供了分布式搜索和索引复制。是最流行的企业级搜索引擎。是一个独立的全文搜索服务器,solr自带分布式实现的协调器。

Solr的缺点:建立索引时,搜索效率下降,实时索引搜索效率不高(实时建立索引时,Solr会产生io阻塞,查询性能较差,Elasticsearch具有更明显的优势)。 Solr的优点:单纯的对已有数据进行搜索时,Solr更快 Solr 是传统搜索应用的有力解决方案,但 Elasticsearch 更适用于新兴的实时搜索应用。 es内对对索引构建采取了多线程,效率比solr高很多

参考:blog.csdn.net/Ms_lang/art…

90,solr和es的一些面试题 blog.csdn.net/Ms_lang/art…

91,Elasticsearch集群部署(整合zk) cluster:代表一个集群,集群中有多个节点,其中有一个为主节点,这个主节点是可以通过选举产生的,主从节点是对于集群内部来说的。es的一个概念就是去中心化,字面上理解就是无中心节点,这是对于集群外部来说的,因为从外部来看es集群,在逻辑上是个整体,你与任何一个节点的通信和与整个es集群通信是等价的。

shards:代表索引分片,es可以把一个完整的索引分成多个分片,这样的好处是可以把一个大的索引拆分成多个,分布到不同的节点上。构成分布式搜索。分片的数量只能在索引创建前指定,并且索引创建后不能更改。

replicas:代表索引副本,es可以设置多个索引的副本,副本的作用一是提高系统的容错性,当某个节点某个分片损坏或丢失时可以从副本中恢复。二是提高es的查询效率,es会自动对搜索请求进行负载均衡。

参考:www.cnblogs.com/aubin/p/801…

92,es集群调优 www.cnblogs.com/guguli/p/52…

93,如何提高ElasticSearch 索引速度 因为ES里大量采用线程池,构建索引的时候,是有单独的线程池做处理的,加大线程池,提高并发处理能力

94,tair原理:

一个Tair集群主要包括3个必选模块:config server、data server和client,以及一个可选模块:invalid server。

通常情况下,一个集群中包含2台config server及多台data server。两台config server互为主备并通过维护和data server之间的心跳获知集群中存活可用的data server, 构建数据在集群中的分布信息(对照表)。Data server负责数据的存储,并按照config server的指示完成数据的复制和迁移工作。 Client在启动的时候,从config server获取数据分布信息,根据数据分布信息和相应的data server交互完成用户的请求。 Invalid server主要负责对等集群的删除和隐藏操作,保证对等集群的数据一致。

从架构上看,config server的角色类似于传统应用系统的中心节点,整个集群服务依赖于config server的正常工作。但实际上相对来说, tair的config server是非常轻量级的,当正在工作的服务器宕机的时候另外一台会在秒级别时间内自动接管。 而且,如果出现两台服务器同时宕机的最恶劣情况,只要应用服务器没有新的变化,tair依然服务正常。 而有了config server这个中心节点,带来的好处就是应用在使用的时候只需要配置config server的地址(现在可以直接配置Diamond key), 而不需要知道内部节点的情况。

ConfigServer的功能 负责管理所有的data server, 维护data server的状态信息。 通过维护和dataserver心跳来获知集群中存活节点的信息 根据存活节点的信息来构建数据在集群中的分布表。 提供数据分布表的查询服务。 调度dataserver之间的数据迁移、复制。

DataServer的功能 对外提供各种数据服务, 并以心跳的形式将自身状况汇报给config server。 提供存储引擎 接受client的put/get/remove等操作 执行数据迁移,复制等 插件:在接受请求的时候处理一些自定义功能 访问统计

InvalidServer的功能 接收来自client的invalid/hide等请求后,对属于同一组的集群(双机房独立集群部署方式)做delete/hide操作,保证同一组集群的一致。 集群断网之后的,脏数据清理。 访问统计。

client的功能 在应用端提供访问Tair集群的接口。 更新并缓存数据分布表和invalidserver地址等。 LocalCache,避免过热数据访问影响tair集群服务。 流控

参考:blog.csdn.net/sunjin9418/…

tair的特点 <1> Tair有四种引擎:mdb, rdb, kdb和ldb。分别基于四种开源的key/value数据库:memcached, Redis, Kyoto Cabinet和leveldb。Tair可以让你更方便地使用这些KV数据库。 Tair默认包含两个存储引擎:mdb和fdb。 <2>Version支持,类似mysql的mvcc机制,支持写入数据时对版本号控制。 <3>多机架和多数据中心的支持 对照表在构建时,可以配置将数据的备份分散到不同机架或数据中心的节点上。Tair当前通过设置一个IP掩码来判断机器所属的机架和数据中心信息。 比如你配置备份数为3,集群的节点分布在两个不同的数据中心A和B,则Tair会确保每个机房至少有一份数据。假设A数据中心包含两份数据时,Tair会尽可能将这两份数据分布在不同机架的节点上。这可以减少整个数据中心或某个机架发生故障是数据丢失的风险。 <4>tair实现了一个集群多中心部署,这是redis 3.0没有实现的。 <5>DataServer负责数据的物理存储,并根据configserver构建的对照表完成数据的复制和迁移工作。DataServer具备抽象的存储引擎层,可以很方便地添加新存储引擎。DataServer还有一个插件容器,可以动态地加载/卸载插件

参考:www.jianshu.com/p/ccb17daed…

tair 的负载均衡算法是什么 tair 的分布采用的是一致性哈希算法, 对于所有的key,分到Q个桶中, 桶是负载均衡和数据迁移的基本单位。 config server 根据一定的策略把每个桶指派到不同的data server上。 因为数据按照key做hash算法, 所以可以认为每个桶中的数据基本是平衡的. 保证了桶分布的均衡性, 就保证了数据分布的均衡性。

tair扩容 数据迁移时data server对外提供服务的策略,假设data server A要把桶1,2,3迁移到data server B,因为迁移完成前,客户端的路由表没有变化,客户端对1,2,3的访问请求都会路由到A,现在假设1还没迁移,2正在迁移,3已经迁移完成,那么如果访问1,则还是访问data server A,如果访问3,则A会把请求转发给B,并且将B的返回结果返回给客户,如果访问2,则在A上处理,同时如果是对2的修改操作,会记录修改log,当桶2完成迁移的时候,还有把log发送给B,在B上应用这些log,最终AB数据一致才是真正完成迁移。如果A是由于宕机而引发的迁移,客户端会收到一张中间临时状态的分配表,把宕机的data server负责的桶临时指派给有其备份的data server来处理,此时服务是可用的,负载可能不均衡,当迁移完成后,又能达到一个新的负载均衡状态

tair的数据备份: config server会发现哪些桶的备份数目减少了, 然后根据负载情况在负载较低的data server上增加这些桶的备份,因此可以理解某个data server的数据是备份在其他的data server 如果是因为某data server宕机而引发的迁移,客户端会收到一张中间临时状态的分配表。 这张表中,把宕机的data server所负责的桶临时指派给有其备份data server来处理。这个时候,服务是可用的,但是负载可能不均衡。 当迁移完成之后,才能重新达到一个新的负载均衡的状态。

参考:blog.csdn.net/death_kada/…

欢迎打赏

转载于:https://juejin.im/post/5cab7682e51d456e577f9311

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值