分布式数据库面试整理

在这里插入图片描述
5.3.1 redis面试专题

1、redis和memcached什么区别?为什么高并发下有时单线程的redis 比多线程的memcached效率要高?

区别:

  1. mc可缓存图片和视频。rd支持除k/v更多的数据结构;

  2. rd可以使用虚拟内存,rd可持久化和aof灾难恢复,rd通过主从支持数 据备份;3.rd可以做消息队列。

原因:mc多线程模型引入了缓存一致性和锁,加锁带来了性能损耗。

2、redis主从复制如何实现的?redis的集群模式如何实现?redis的key 是如何寻址的?

主从复制实现:主节点将自己内存中的数据做一份快照,将快照发给从节 点,从节点将数据恢复到内存中。之后再每次增加新数据的时候,主节点 以类似于mysql的二进制日志方式将语句发送给从节点,从节点拿到主节 点发送过来的语句进行重放。

分片方式:

-客户端分片

一基于代理的分片

• Twemproxy

• codis

-路由查询分片

• Redis-cluster体身提供了自动将数据分散到Redis Cluster不同节点的能 力,整个数据集合的某个数据子集存储在哪个节点对于用户来说是透明的) redis-cluster分片原理:Cluster中有一个16384长度的槽(虚拟槽),编号分 别为0-16383。每个Master节点都会负责一部分的槽,当有某个key被 映射到某个Master负责的槽,那么这个Master负责为这个key提供服 务,至于哪个Master节点负责哪个槽,可以由用户指定,也可以在初始 化的时候自动生成,只有Master才拥有槽的所有权。Master节点维护着 一个16384/8字节的位序列,Master节点用bit来标识对于某个槽自己是 否拥有。比如对于编号为1的槽,Master只要判断序列的第二位(索引从 0开始)是不是为1即可。这种结构很容易添加或者删除节点。比如如果我 想新添加个节点D,我需要从节点A、B、C中得部分槽到D上。

3、使用redis如何设计分布式锁?说一下实现思路?使用zk可以吗?如何

实现?这两种有什么区别?

redis:

  1. 线程A setnx(上锁的对象超时时的时间戳tl),如果返回true,获得锁。

  2. 线程B用get获取t1,与当前时间戳比较,判断是是否超时,没超时false, 若超时执行第3步;

  3. 计算新的超时时间t2,使用getset命令返回t3(该值可能其他线程已经修 改过),如果t1==t3,获得锁,如果t1!=t3说明锁被其他线程获取了。

  4. 获取锁后,处理完业务逻辑,再去判断锁是否超时,如果没超时删除 锁,如果已超时,不用处理(防止删除其他线程的锁)。

zk:

  1. 客户端对某个方法加锁时,在zk上的与该方法对应的指定节点的目录 下,生成一个唯一的瞬时有序节点node1;

  2. 客户端获取该路径下所有已经创建的子节点,如果发现自己创建的 node1的序号是最小的,就认为这个客户端获得了锁。

  3. 如果发现node1不是最小的,则监听比自己创建节点序号小的最大的节 点,进入等待。

  4. 获取锁后,处理完逻辑,删除自己创建的node1即可。区别:zk性能差 一些,开销大,实现简单。

4、知道redis的持久化吗?底层如何实现的?有什么优点缺点?

RDB(Redis DataBase:在不同的时间点将redis的数据生成的快照同步到磁 盘等介质上):内存到硬盘的快照,定期更新。缺点:耗时,耗性能(fork+io操 作),易丢失数据。

AOF(Append Only File:将redi s所执行过的所有指令都记录下来,在下次 redis重启时,只需要执行指令就可以了):写日志。缺点:体积大,恢复速度 慢。

bgsave做镜像全量持久化,aof做增量持久化。因为bgsave会消耗比较 长的时间,不够实时,在停机的时候会导致大量的数据丢失,需要aof来 配合,在redis实例重启时,优先使用aof来恢复内存的状态,如果没有 aof日志,就会使用rdb文件来恢复。Redis会定期做aof重写,压缩aof 文件日志大小。Redis4.0之后有了混合持久化的功能,将bgsave的全量 和aof的增量做了融合处理,这样既保证了恢复的效率又兼顾了数据的安 全性。bgsave的原理,fork和cow, fork是指redis通过创建子进程来进 行bgsave操作,cow指的是copy on write,子进程创建后,父子进程共 享数据段,父进程继续提供读写服务,写脏的页面数据会逐渐和子进程分 囲开来。

5、redis过期策略都有哪些?LRU算法知道吗?写一下java代码实现?

过期策略:

定时过期(一key 一定时器),惰性过期:只有使用key时才判断key是否已 过期,过期则清除。定期过期:前两者折中。

LRU:new LinkedHashMap<K, V>(capacity, DEFAULT_LOAD_FACTORY, tr ue);

〃第三个参数置为true,代表linkedlist按访问顺序排序,可作为LRU缓存 ;设为false代表按插入顺序排序,可作为FIFO缓存

LRU算法实现:

  1. 通过双向链表来实现,新数据插入到链表头部;

  2. 每当缓存命中(即缓存数据被访问),则将数据移到链表头部;

  3. 当链表满的时候,将链表尾部的数据丢弃。

LinkedHashMap:HashMap 和双向链表合二为一即是 LinkedHashMap。 HashMap是无序的,LinkedHashMap通过维护一个额外的双向链表保证 了迭代顺序。该迭代顺序可以是插入顺序(默认),也可以是访问顺序。

6、缓存穿透、缓存击穿、缓存雪崩解决方案?

缓存穿透:指查询一个一定不存在的数据,如果从存储层查不到数据则不写 入缓存,这将导致这个不存在的数据每次请求都要到DB去查询,可能导 致DB挂掉。

解决方案:

  1. 查询返回的数据为空,仍把这个空结果进行缓存,但过期时间会比较短;

  2. 布隆过滤器:将所有可能存在的数据哈希到一个足够大的bitmap中,一 个一定不存在的数据会被这个bitmap拦截掉,从而避免了对DB的查 询。

缓存击穿:对于设置了过期时间的key,缓存在某个时间点过期的时候,恰 好这时间点对这个Key有大量的并发请求过来,这些请求发现缓存过期一 般都会从后端DB加载数据并回设到缓存,这个时候大并发的请求可能会 瞬间把DB压垮。

解决方案:

  1. 使用互斥锁:当缓存失效时,不立即去I oad db,先使用如Redis的setnx去 设置一个互斥锁,当操作成功返回时再进行I oad db的操作并回设缓存,否 则重试get缓存的方法。

  2. 永远不过期:物理不过期,但逻辑过期(后台异步线程去刷新)。缓存雪崩: 设置缓存时采用了相同的过期时间,导致缓存在某一时刻同时失效,请求 全部转发到DB, DB瞬时压力过重雪崩。与缓存击穿的区别:雪崩是很多 key,击穿是某一个key缓存。

解决方案:将缓存失效时间分散开,比如可以在原有的失效时间基础上增加 一个随机值,比如1-5分钟随机,这样每一个缓存的过期时间的重复率就 会降低,就很难引发集体失效的事件。

7、在选择缓存时,什么时候选择redis,什么时候选择memcached 选择redis的情况:

1、 复杂数据结构,value的数据是哈希,列表,集合,有序集合等这种情 况下,会选择redis,因为memcache无法满足这些数据结构,最典型的的 使用场景是,用户订单列表,用户消息,帖子评论等。

2、 需要进行数据的持久化功能,但是注意,不要把redis当成数据库使 用,如果redis挂了,内存能够快速恢复热数据,不会将压力瞬间压在数 据库上,没有cache预热的过程。对于只读和数据一致性要求不高的场景 可以采用持久化存储

3、 高可用,redis支持集群,可以实现主动复制,读写分离,而对于 memcache如果想要实现高可用,需要进行二次开发。

4、 存储的内容比较大,memcache存储的value最大为1M。

选择 memcache的场景:

1、纯KV,数据量非常大的业务,使用memcache更合适,原因是,

a) memcache的内存分配采用的是预分配内存池的管理方式,能够省去内 存分配的时间,redis是临时申请空间,可能导致碎片化。

b) 虚拟内存使用,memcache将所有的数据存储在物理内存里,redis有自 己的vm机制,理论上能够存储比物理内存更多的数据,当数据超量时, 引发swap,把冷数据刷新到磁盘上,从这点上,数据量大时,memcache 更快

c) 网络模型,memcache使用非阻塞的10复用模型,redis也是使用非阻 塞的I。复用模型,但是redis还提供了一些非KV存储之外的排序,聚合 功能,复杂的CPU计算,会阻塞整个I0调度,从这点上由于redis提供 的功能较多,memcache更快些

d) 线程模型,memcache使用多线程,主线程监听,worker子线程接受请 求,执行读写,这个过程可能存在锁冲突。redis使用的单线程,虽然无锁 冲突,但是难以利用多核的特性提升吞吐量。

8、 缓存与数据库不一致怎么办

假设采用的主存分离,读写分离的数据库,

如果一个线程A先删除缓存数据,然后将数据写入到主库当中,这个时 候,主库和从库同步没有完成,线程B从缓存当中读取数据失败,从从 库当中读取到旧数据,然后更新至缓存,这个时候,缓存当中的就是旧的 数据。

发生上述不一致的原因在于,主从库数据不一致问题,加入了缓存之后, 主从不一致的时间被拉长了

处理思路:在从库有数据更新之后,将缓存当中的数据也同时进行更新,即 当从库发生了数据更新之后,向缓存发出删除,淘汰这段时间写入的旧数 据。

9、 主从数据库不一致如何解决

场景描述,对于主从库,读写分离,如果主从库更新同步有时差,就会导 致主从库数据的不一致

1、 忽略这个数据不一致,在数据一致性要求不高的业务下,未必需要时 时一致性

2、 强制读主库,使用一个高可用的主库,数据库读写都在主库,添加一 个缓存,提升数据读取的性能。

3、 选择性读主库,添加一个缓存,用来记录必须读主库的数据,将哪个 库,哪个表,哪个主键,作为缓存的key,设置缓存失效的时间为主从库同 步的时间,如果缓存当中有这个数据,直接读取主库,如果缓存当中没有 这个主键,就到对应的从库中读取。

10、 Redis常见的性能问题和解决方案

1、 master最好不要做持久化工作,如RDB内存快照和AOF日志文件

2、 如果数据比较重要,某个slave开启AOF备份,策略设置成每秒同步 一次

3、 为了主从复制的速度和连接的稳定性,master和Slave最好在一个局 域网内

4、 尽量避免在压力大得主库上增加从库

5、 主从复制不要米用网状结构,尽量是线性结构,Master<–Slave1<— Slave2 …

11、 Redis的数据淘汰策略有哪些

voltile-lru从已经设置过期时间的数据集中挑选最近最少使用的数据淘汰 voltile-ttl从已经设置过期时间的数据库集当中挑选将要过期的数据 voltile-random从已经设置过期时间的数据集任意选择淘汰数据allkeys-lru 从数据集中挑选最近最少使用的数据淘汰

allkeys-random从数据集中任意选择淘汰的数据no-eviction禁止驱逐数据

12、 Redis当中有哪些数据结构

字符串String、字典Hash、列表List、集合Set、有序集合SortedSet。 如果是咼级用户,那么还会有,如果你是Redis中咼级用户,还需要加上 下面几种数据结构HyperLogLog、Geo、Pub/Sub。

13、 假如Redis里面有1亿个key,其中有10w个key是以某个固定的 已知的前缀开头的,如果将它们全部找出来?

使用keys指令可以扫出指定模式的key列表。

对方接着追问:如果这个redis正在给线上的业务提供服务,那使用keys 指令会有什么问题?

这个时候你要回答redis关键的一个特性:redis的单线程的。keys指令会 导致线程阻塞一段时间,线上服务会停顿,直到指令执行完毕,服务才能 恢复。这个时候可以使用scan指令,scan指令可以无阻塞的提取出指定 模式的key列表,但是会有一定的重复概率,在客户端做一次去重就可以 了,但是整体所花费的时间会比直接用keys指令长。

14、 使用Redis做过异步队列吗,是如何实现的

使用list类型保存数据信息,rpush生产消息,lpop消费消息,当lpop没 有消息时,可以sleep 一段时间,然后再检查有没有信息,如果不想 sleep的话,可以使用blpop,在没有信息的时候,会一直阻塞,直到信息 的到来。redis可以通过pub/sub主题订阅模式实现一个生产者,多个消 费者,当然也存在一定的缺点,当消费者下线时,生产的消息会丢失。

15、 Redis如何实现延时队列

使用sortedset,使用时间戳做score,消息内容作为key,调用zadd来生产 消息,消费者使用zrangbyscore获取n秒之前的数据做轮询处理。

16、 什么是Redis ?简述它的优缺点?

Redis本质上是一个Key-Value类型的内存数据库,很像memcached,整 个数据库统统加载在内存当中进行操作,定期通过异步操作把数据库数据 flush到硬盘上进行保存。

因为是纯内存操作,Redis的性能非常出色,每秒可以处理超过10万次读 写操作,是已知性能最快的Key-Value DB。

Redis的出色之处不仅仅是性能,Redis最大的魅力是支持保存多种数据

结构,此外单个value的最大限制是1GB,不像memcached只能保存 1MB的数据,因此Redis可以用来实现很多有用的功能。

比方说用他的List来做FIFO双向链表,实现一个轻量级的高性能消息队 列服务,用他的Set可以做高性能的tag系统等等。

另外Redi s也可以对存入的Key-Value设置expire时间,因此也可以被当作一 个功能加强版的memcac hed来用。Redis的主要缺点是数据库容量受到 物理内存的限制,不能用作海量数据的高性能读写,因此Redis适合的场 景主要局限在较小数据量的高性能操作和运算上。

17、 Redis相比memcached有哪些优势?

⑴memcached所有的值均是简单的字符串,redis作为其替代者,支持更 为丰富的数据类型

⑵redis的速度比memcached快很多

(3) redi s可以持久化其数据

18、 Redis支持哪几种数据类型?

String、List、Set、Sorted Set、hashes

19、 Redis主要消耗什么物理资源?

内存。

20、 Redis的全称是什么?

Remote Dictionary Server o

21、 Redis有哪几种数据淘汰策略?

noeviction:返回错误当内存限制达到并且客户端尝试执行会让更多内存被 使用的命令(大部分的写入指令,但DEL和几个例外)

allkeys-lru:尝试回收最少使用的键(LRU),使得新添加的数据有空间存放。 volatile-lru:尝试回收最少使用的键(LRU),但仅限于在过期集合的键,使得 新添加的数据有空间存放。

allkeys-random:回收随机的键使得新添加的数据有空间存放。 volatile-random:回收随机的键使得新添加的数据有空间存放,但仅限于在 过期集合的键。

volatile-ttl:回收在过期集合的键,并且优先回收存活时间(TTL)较短的键,使 得新添加的数据有空间存放。

22、 Redis官方为什么不提供Windows版本?

因为目前Linux版本已经相当稳定,而且用户量很大,无需开发windows 版本,反而会带来兼容性等问题。

23、 一个字符串类型的值能存储最大容量是多少?

512M

24、 为什么Redis需要把所有数据放到内存中?

Redis为了达到最快的读写速度将数据都读到内存中,并通过异步的方式 将数据写入磁盘。

所以redis具有快速和数据持久化的特征。如果不将数据放在内存中,磁 盘I/O速度为严重影响redis的性能。

在内存越来越便宜的今天,redis将会越来越受欢迎。如果设置了最大使用 的内存,则数据已有记录数达到内存限值后不能继续插入新值。

25、 Redis集群方案应该怎么做?都有哪些方案?

  1. codis。

目前用的最多的集群方案,基本和twemproxy 一致的效果,但它支持在节 点数量改变情况下,旧节点数据可恢复到新hash节点。

  1. redis cluster3.0自带的集群,特点在于他的分布式算法不是一致性 hash,而是hash槽的概念,以及自身支持节点设置从节点。具体看官方文 档介绍。

  2. 在业务代码层实现,起几个毫无关联的redis实例,在代码层,对key进 行hash计算,然后去对应的redis实例操作数据。这种方式对hash层代码 要求比较高,考虑部分包括,节点失效后的替代算法方案,数据震荡后的 自动脚本恢复,实例的监控,等等。

26、 Redis集群方案什么情况下会导致整个集群不可用?

有A, B, C三个节点的集群,在没有复制模型的情况下,如果节点B失败 了,那么整个集群就会以为缺少5 501-11000这个范围的槽而不可用。

27、 MySQL里有2000w数据,redis中只存20w的数据,如何保证 redis中的数据都是热点数据?

redis内存数据集大小上升到一定大小的时候,就会施行数据淘汰策略。

28、 Redis有哪些适合的场景?

⑴会话缓存(Session Cache)

最常用的一种使用Redis的情景是会话缓存(session cache)。用Redis缓存 会话比其他存储(如Mem cached)的优势在于:Redis提供持久化。当维护一 个不是严格要求一致性的缓存时,如果用户的购物车信息全部丢失,大部 分人都会不高兴的,现在,他们还会这样吗?

幸运的是,随着Redis这些年的改进,很容易找到怎么恰当的使用Redis 来缓存会话的文档。甚至广为人知的商业平台Magento也提供Redis的插 件。

⑵全页缓存(FPC)

除基本的会话token之外,Redis还提供很简便的FPC平台。回到一致性 问题,即使重启了 Redis实例,因为有磁盘的持久化,用户也不会看到页 面加载速度的下降,这是一个极大改进,类似PHP本地FPC。

再次以Magento为例,Magento提供一个插件来使用Redis作为全页缓 存后端。

此外,对WordPress的用户来说,Pantheon有一个非常好的插件wp- redis,这个插件能帮助你以最快 速度加载你曾浏览过的页面。

(3)队列

Reids在内存存储引擎领域的一大优点是提供list和set操作,这使得 Redis能作为一个很好的消息队列平台来使用。Redis作为队列使用的操 作,就类似于本地程序语言(如Python)对list的push/pop操作。

如果你快速的在Google中搜索"Redis queues",你马上就能找到大量的开 源项目,这些项目的目的就是利用Redis创建非常好的后端工具,以满足 各种队列需求。例如,Celery有一个后台就是使用Redis作为broker,你 可以从这里去查看。

⑷排行榜/计数器

Redis在内存中对数字进行递增或递减的操作实现的非常好。集合(Set )和 有序集合(Sorted Set )也

使得我们在执行这些操作的时候变的非常简单,Redis只是正好提供了这 两种数据结构。所以,我们要从排序集合中获取到排名最靠前的10个用 户-我们称之为“user_scores”,我们只需要像下

面一样执行即可:

当然,这是假定你是根据你用户的分数做递增的排序。如果你想返回用户 及用户的分数,你需要这样执行:

ZRANGE user_scores 0 10 WITHSCORES

Agora Games就是一个很好的例子,用Ruby实现的,它的排行榜就是使 用Redis来存储数据的,你可以在这里看到。

⑸发布/订阅

最后(但肯定不是最不重要的)是Redis的发布/订阅功能。发布/订阅的使用 场景确实非常多。我已看见人们在社交网络连接中使用,还可作为基于发 布/订阅的脚本触发器,甚至用Redis的发布/订阅功能来建立聊天系统!

29、 Redis支持的Java客户端都有哪些?官方推荐用哪个?

Redisson、Jedis、lettuce 等等,官方推荐使用 Redisson。

30、 Redis和Redisson有什么关系?

Redisson是一个高级的分布式协调Redis客服端,能帮助用户在分布式环 境中轻松实现一些 Java 的对象(Bloom filter, BitSet, Set, SetMultimap, ScoredSortedSet, SortedSet, Map, ConcurrentMap, List, List Multimap, Queue, BlockingQueue, Deque, BlockingDeque, Semaphore, Lock, ReadWriteLock, Atomi cLong, CountDownLatch, Publish / Subscribe, HyperLogLog)。

31、 Jedis与Redisson对比有什么优缺点?

Jedis是Redis的Java实现的客户端,其API提供了比较全面的Redis命 令的支持;

Redisson实现了分布式和可扩展的Java数据结构,和Jedis相比,功能 较为简单,不支持字符串操作,不支持排序、事务、管道、分区等Redis 特性。Redisson的宗旨是促进使用者对Redis的关注分离,从而让使用者 能够将精力更集中地放在处理业务逻辑上。

32、 Redis如何设置密码及验证密码? 设置密码:c onfig set requirepass 123456 授权密码:auth 123456

33、 说说Redis哈希槽的概念?

Redis集群没有使用一致性hash,而是引入了哈希槽的概念,Redis集群有 16384个哈希槽,每个key通过CRC16校验后对16384取模来决定放置 哪个槽,集群的每个节点负责一部分hash槽。

34、 Redis集群的主从复制模型是怎样的?

为了使在部分节点失败或者大部分节点无法通信的情况下集群仍然可用, 所以集群使用了主从复制模型,每个节点都会有N-1个复制品.

35、 Redis集群会有写操作丢失吗?为什么?

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

36、Redis集群之间是如何复制的?

异步复制

37、 Redis集群最大节点个数是多少?

16384 个。

38、 Redis集群如何选择数据库?

Redis集群目前无法做数据库选择,默认在0数据库。

39、 怎么测试Redis的连通性?

ping

40、 Redis中的管道有什么用?

一次请求/响应服务器能实现处理新的请求即使旧的请求还未被响应。这样 就可以将多个命令发送到服务器,而不用等待回复,最后在一个步骤中读 取该答复。

这就是管道(pipelining),是一种几十年来广泛使用的技术。例如许多POP3 协议已经实现支持这个功能,大大加快了从服务器下载新邮件的过程。

41、 怎么理解Redis事务?

事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执 行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。 事务是一个原子操作:事务中的命令要么全部被执行,要么全部都不执行。

42、 Redis事务相关的命令有哪几个?

MULTI、EXEC、DISCARD、WATCH

43、 Redis key的过期时间和永久有效分别怎么设置?

EXPIRE 和 PERSIST 命令。

44、 Redis如何做内存优化?

尽可能使用散列表(hashes),散列表(是说散列表里面存储的数少)使用的内 存非常小,所以你应该尽可能的将你的数据模型抽象到一个散列表里面。 比如你的web系统中有一个用户对象,不要为这个用户的名称,姓氏, 邮箱,密码设置单独的key,而是应该把这个用户的所有信息存储到一张散 列表里面。

45、 Redis回收进程如何工作的?

一个客户端运行了新的命令,添加了新的数据。

Redi检查内存使用情况,如果大于maxmemory的限制,则根据设定好的 策略进行回收。

一个新的命令被执行,等等。

所以我们不断地穿越内存限制的边界,通过不断达到边界然后不断地回收 回到边界以下。

如果一个命令的结果导致大量内存被使用(例如很大的集合的交集保存到一 个新的键),不用多久内存限制就会被这个内存使用量超越。

5.3.2 MongoDB面试专题

  1. 你说的NoSQL数据库是什么意思?NoSQL与RDBMS直接有什么区 别?为什么要使用和不使用NoSQL数据库?说一说NoSQL数据库的几个 优点?

NoSQL是非关系型数据库,NoSQL = Not Only SQL。

关系型数据库采用的结构化的数据,NoSQL采用的是键值对的方式存储 数据。

在处理非结构化/半结构化的大数据时;在水平方向上进行扩展时;随时应对 动态增加的数据项时可以优先考虑使用NoSQL数据库。

在考虑数据库的成熟度;支持;分析和商业智能;管理及专业性等问题时,应 优先考虑关系型数据库。

  1. NoSQL数据库有哪些类型?

例如:MongoDB, Cassandra, CouchDB, Hypertable, Redis, Riak, Neo4j, HBASE, Couchbase, MemcacheDB, RevenDB and Voldemort are the examples of NoSQL databases.

  1. MySQL与MongoDB之间最基本的差别是什么?

MySQL和MongoDB两者都是免费开源的数据库。MySQL和MongoDB 有许多基本差别包括数据的表示(data representation),查询,关系,事 务,schema的设计和定义,标准化(normalization),速度和性能。

通过比较MySQL和MongoDB,实际上我们是在比较关系型和非关系型 数据库,即数据存储结构不同。

  1. 你怎么比较 MongoDB、CouchDB 及 CouchBase?

MongoDB和CouchDB都是面向文档的数据库。MongoDB和CouchDB 都是开源NoSQL数据库的最典型代表。除了都以文档形式存储外它们没 有其他的共同点。MongoDB和CouchDB在数据模型实现、接口、对象 存储以及复制方法等方面有很多不同。

  1. MongoDB成为最好NoSQL数据库的原因是什么? 以下特点使得MongoDB成为最好的NoSQL数据库:

•面向文件的

•高性能

•高可用性

•易扩展性

•丰富的查询语言

  1. 32位系统上有什么细微差别?

journaling会激活额外的内存映射文件。这将进一步抑制32位版本上的数 据库大小。因此,现在journaling在32位系统上默认是禁用的。

  1. journal回放在条目(entry)不完整时(比如恰巧有一个中途故障了)会遇到 问题吗?

每个journal (group)的写操作都是一致的,除非它是完整的否则在恢复过 程中它不会回放。

  1. 分析器在MongoDB中的作用是什么?

MongoDB中包括了一个可以显示数据库中每个操作性能特点的数据库分 析器。通过这个分析器你可以找到比预期慢的查询(或写操作);利用这一信 息,比如,可以确定是否需要添加索引。

  1. 名字空间(namespace )是什么?

MongoDB存储BSON对象在丛集(c ollection)中。数据库名字和丛集名字 以句点连结起来叫做名字空间(namespace)。

  1. 如果用户移除对象的属性,该属性是否从存储层中删除?

是的,用户移除属性然后对象会重新保存(re-save。)。

  1. 能否使用日志特征进行安全备份?

是的。

  1. 允许空值null吗?

对于对象成员而言,是的。然而用户不能够添加空值(null)到数据库丛集 (collection)因为空值不是对象。然而用户能够添加空对象{}。

  1. 更新操作立刻fsync到磁盘?

不会,磁盘写操作默认是延迟执行的。写操作可能在两三秒(默认在60秒 内)后到达磁盘。例如,如果一秒内数据库收到一千个对一个对象递增的操 作,仅刷新磁盘一次。(注意,尽管fsync选项在命令行和经过 getLastError_old是有效的)(译者:也许是坑人的面试题??)。

  1. 如何执行事务/加锁?

MongoDB没有使用传统的锁或者复杂的带回滚的事务,因为它设计的宗 旨是轻量,快速以及可预计的高性能。可以把它类比成MySQL MylSAM 的自动提交模式。通过精简对事务的支持,性能得到了提升,特别是在一 个可能会穿过多个服务器的系统里。

  1. 为什么我的数据文件如此庞大?

MongoDB会积极的预分配预留空间来防止文件系统碎片。

  1. 启用备份故障恢复需要多久?

从备份数据库声明主数据库宕机到选出一个备份数据库作为新的主数据库 将花费10到30秒时间。这期间在主数据库上的操作将会失败-包括写入 和强一致性读取(strong consistent read)操作。然而,你还能在第二数据库 上执行最终一致性查询(eventually consistent query)(在slaveOk模式下), 即使在这段时间里。

  1. 什么是 master 或 primary?

它是当前备份集群(replica set )中负责处理所有写入操作的主要节点/成员。 在一个备份集群中,当失效备援(failover)事件发生时,一个另外的成员会 变成 primary。

  1. 什么是 secondary 或 slave?

Seconday从当前的primary上复制相应的操作。它是通过跟踪复制 oplog(local.oplog.rs)做到的。

  1. 我必须调用getLastError来确保写操作生效了么?

不用。不管你有没有调用getLastError(又叫"Safe Mode")服务器做的操作 都一样。调用getLastError只是为了确认写操作成功提交了。当然,你经 常想得到确认,但是写操作的安全性和是否生效不是由这个决定的。

  1. 我应该启动一个集群分片(sharded )还是一个非集群分片的MongoDB 环境?

为开发便捷起见,我们建议以非集群分片(unsharded)方式开始一个 MongoDB环境,除非一台服务器不足以存放你的初始数据集。从非集群 分片升级到集群分片(sharding)是无缝的,所以在你的数据集还不是很大 的时候没必要考虑集群分片(sharding)。

  1. 分片(sharding)和复制(replication)是怎样工作的?

每一个分片(shard)是一个分区数据的逻辑集合。分片可能由单一服务器或

者集群组成,我们推荐为每一个分片(shard)使用集群。

  1. 数据在什么时候才会扩展到多个分片(shard)里?

MongoDB分片是基于区域(range)的。所以一个集合(collection)中的所有的 对象都被存放到一个块(chunk)中。只有当存在多余一个块的时候,才会 有多个分片获取数据的选项。现在,每个默认块的大小是64Mb,所以你 需要至少64 Mb空间才可以实施一个迁移。

  1. 当我试图更新一个正在被迁移的块(chunk)上的文档时会发生什么? 更新操作会立即发生在旧的分片(shard)上,然后更改才会在所有权转移 (ownership transfers )前复制到新的分片上。

  2. 如果在一个分片(shard)停止或者很慢的时候,我发起一个查询会怎 样?

如果一个分片(shard)停止了,除非查询设置了 "Partial"选项,否则查询会返 回一个错误。如果一个分片(shard)响应很慢,MongoDB则会等待它的响 应。

  1. 我可以把moveChunk目录里的旧文件删除吗?

没问题,这些文件是在分片(shard)进行均衡操作(balancing)的时候产生的 临时文件。一旦这些操作已经完成,相关的临时文件也应该被删除掉。但 目前清理工作是需要手动的,所以请小心地考虑再释放这些文件的空间。

  1. 我怎么查看Mongo正在使用的链接?

db._adminCommand(HconnPoolStatsH);

  1. 如果块移动操作(moveChunk)失败了,我需要手动清除部分转移的文 档吗?

不需要,移动操作是一致(consistent )并且是确定性的(deterministic);一次失 败后,移动操作会不断重试;当完成后,数据只会出现在新的分片里 (shard)。

  1. 如果我在使用复制技术(replication),可以一部分使用日志 (journaling)而其他部分则不使用吗?

可以。

  1. 当更新一个正在被迁移的块(Chunk)上的文档时会发生什么?

更新操作会立即发生在旧的块(Chunk)上,然后更改才会在所有权转移前复 制到新的分片上。

  1. MongoDB在A:{B,C}上建立索引,查询A:{B,C}和A:{C,B}都会使用索 引吗?

不会,只会在A:{B,C}上使用索引。

  1. 如果一个分片(Shard)停止或很慢的时候,发起一个查询会怎样? 如果一个分片停止了,除非查询设置了“Partial"选项,否则查询会返回一 个错误。如果一个分片响应很慢,MongoDB会等待它的响应。

  2. MongoDB支持存储过程吗?如果支持的话,怎么用?

MongoDB支持存储过程,它是javascript写的,保存在db.system.js表 中。

  1. 如何理解MongoDB中的GridFS机制,MongoDB为何使用GridFS 来存储文件?

GridFS是一种将大型文件存储在MongoDB中的文件规范。使用GridFS 可以将大文件分隔成多个小文档存放,这样我们能够有效的保存大文档, 而且解决了 BSON对象有限制的问题。

5.3.3 memcached 面试专题

1、memcached是怎么工作的?

Memcached的神奇来自两阶段哈希(two-stagehash)。Memcached就像一 个巨大的、存储了很多<key,value>对的哈希表。通过key,可以存储或 查询任意的数据。

客户端可以把数据存储在多台memcached上。当查询数据时,客户端首 先参考节点列表计算出key的哈希值(阶段一哈希),进而选中一个节点;客 户端将请求发送给选中的节点,然后memcached节点通过一个内部的哈 希算法(阶段二哈希),查找真正的数据(item)。

举个列子,假设有3个客服端1 2 3台memcached A,B,C Client 1想把数据"barbaz”以key “foo"存储。Client 1首先参考节点列表

(A, B, C)计算key "foo”的哈希值,假设memcached B被选中。接 着,Client 1 直接 connect 到memcached B 通过 key "foo"把数 据"barbaz"存储进去。Client 2使用与Client 1相同的客户端库億味着阶 段一的哈希算法相同),也拥有同样的memcached列表(A, B, C)。 于是,经过相同的哈希计算(阶段一),Client 2计算出key “foo"在 memcached B上,然后它直接请求memcached B,得到数据"barbaz”。 各种客户端在memcached中数据的存储形式是不同的(perl Storable php serialize,java hibernate,JSON等)。一些客户端实现的哈希算法也不一 样。但是,memcached服务器端的行为总是一致的。

最后,从实现的角度看,memcached是一个非阻塞的、基于事件的服务 器程序。这种架构可以很好地解决C10K problem,并具有极佳的可扩展 性。

可以参考A Story of Caching,这篇文章简单解释了客户端与memcached 是如何交互的。

2、 memcached最大的优势是什么?

请仔细阅读上面的问题(即memcached是如何工作的)。Memcached最大 的好处就是它带来了极佳的水平可扩展性,特别是在一个巨大的系统中。

由于客户端自己做了一次哈希,那么我们很容易增加大量memcached到 集群中。memcached之间没有相互通信,因此不会增加memcached的 负载;没有多播协议,不会网络通信量爆炸(implode)o memcached的集群 很好用。内存不够了?增加几台memcached吧;CPU不够用了?再增加几 台吧;有多余的内存?在增加几台吧,不要浪费了。

基于memcached的基本原则,可以相当轻松地构建出不同类型的缓存架 构。除了这篇FAQ,在其他地方很容易找到详细资料的。

3、 memcached和MySQL的query cache相比有什么优缺点?

把memcached引入应用中,还是需要不少工作量的。MySQL有个使用 方便的query cache,可以自动地缓存SQL查询的结果,被缓存的SQL 查询可以被反复地快速执行。Memcached与之相比,怎么样呢? MySQL 的query cache是集中式的,连接到该query cache的MySQL服务器都 会受益。

•当您修改表时,MySQL的query cache会立刻被刷新(flush)。存储一个 memcached item只需要很少的时间,但是当写操作很频繁时,MySQL的 query cache会经常让所有缓存数据都失效。

•在多核CPU上MySQL的query cache会遇到扩展问题(scalability issues )。在多核CPU上query cache会增加一个全局锁(global lock)、由 于需要刷新更多的缓存数据,速度会变得更慢。

•在MySQL的query cache中,我们是不能存储任意的数据的(只能是 SQL查询结果)。而利用memcached,我们可以搭建出各种高效的缓存。 比如,可以执行多个独立的查询,构建出一个用户对象(user object),然后 将用户对象缓存到memcached中,而query cache是SQL语句级别的, 不可能做到这一点。在小的网站中,query cache会有所帮助,但随着网 站规模的增加,query cache的弊将大于利。

• query cache能够利用的内存容量受到MySQL服务器空闲内存空间的限 制。给数据库服务器增加更多的内存来缓存数据,固然是很好的。但是, 有了 memcached,只要您有空闲的内存,都可以用来增加memcached 集群的规模,然后您就可以缓存更多的数据。

4、 memcached 和服务器的 local cache (比如 PHP 的 APC、mmap 文 件等)相比,有什么优缺点?

首先,local cache有许多与上面(query cache)相同的问题。local cache能 够利用的内存容量受到(单台)服务器空闲内存空间的限制。不过,local cache有一点比memcached和query cache都要好,那就是它不但可以 存储任意的数据,而且没有网络存取的延迟。

• local cache的数据查询更快。考虑把highly common的数据放在local cache中吧。如果每个页面都需要加载一些数量较少的数据,考虑把它们 放在 local cach e 吧。

• local cache 缺少集体失效(group invalidatio n)的特性,在 memcached 集 群中,删除或更新一个key会让所有的观察者觉察到。但是在local cache 中我们只能通知所有的服务器刷新cache(很慢,不具扩展性),或者仅仅依 赖缓存超时失效机制。

• local cache面临着严重的内存限制,这一点上面已经提到。

5、 memcached的cache机制是怎样的?

Memcached主要的cache机制是LRU最近最少用)算法+超时失效。当您 存数据到memcached中,可以指定该数据在缓存中可以呆多久Which is forever,or some time in the futureo 如果 memcached 的内存不够用了,过 期的slabs会优先被替换,接着就轮到最老的未被使用的slabs

6、memcached如何实现冗余机制?

不实现!我们对这个问题感到很惊讶。Memcached应该是应用的缓存层。 它的设计本身就不带有任何冗余机制。如果一个Memcached节点失去了 所有数据,您应该可以从数据源(比如数据库)再次获取到数据。您应该特 别注意,您的应用应该可以容忍节点的失效。不要写一些糟糕的查询代 码,寄希望于memcached来保证一切!如果您担心节点失效会大大加重数 据库的负担,那么您可以采取一些办法。比如您可以增加更多的节点(来减 少丢失一个节点的影响),热备节点(在其他节点down 了的时候接管IP)

AA AA

寺。

7、memcached如何处理容错的? 不处理!在memcached节点失效的情况下,集群没有必要做任何容错处 理。如果发生了节点失效,应对的措施完全取决于用户。节点失效时,下 面列出几种方案供您选择:

•忽略它!失效节点被恢复或替换之前,还有很多其他节点可以应对节点 失效带来的影响。

•把失效的节点从节点列表中移除。做这个操作千万要小心!在默认情况 下(余数式哈希算法),客户端添加或移除节点,会导致所有的缓存数据 不可用!因为哈希参照的节点列表变化了,大部分key会因为哈希值的改 变而被映射到(与原来)不同的节点上。

•启动热备节点,接管失效节点所占用的IP,这样可以防止哈希紊乱 (hashing chaos)。

•如果希望添加和移除节点,而不影响原先的哈希结果,可以使用一致性 哈希算法(consistent hashing)。您可以百度一下一致性哈希算法。支持一 致性哈希的客户端已经很成熟,而且被广泛使用。去尝试一下吧!

•两次哈希(reshing)。当客户端存取数据时,如果发现一个节点(down) 了,就再做一次哈希(哈希算法与前一次不同),重新选择另一个节点(需要 注意的时,客户端并没有把down的节点从节点列表中移除,下次还是有 可能先哈希到它)。如果某个节点时好时坏,两次哈希的方法就有风险了, 好的节点和坏的节点上都可能存在脏数据(stale data)。

8、 如何将memcached中item批量导入导出?

您不应该这样做!Memcached是一个非阻塞的服务器。任何可能导致 memcached暂停或瞬时拒绝服务的操作都应该值得深思熟虑。向 memcached中批量导入数据往往不是您真正想要的!想象看,如果缓存数 据在导出导入之间发生了变化,您就需要处理脏数据了;如果缓存数据在导 出导入之间过期了,您又怎么处理这些数据呢?

因此,批量导出导入数据并不像您想象中的那么有用。不过在一个场景倒 是很有用。如果您有大量的从不变化的数据,并且希望缓存很快热(warm) 起来,批量导入缓存数据是很有帮助的。虽然这个场景并不典型,但却经 常发生,因此我们会考虑在将来实现批量导出导入的功能。

Steven Grimm,一如既往地,在邮件列表中给出了另一个很好的例

子:http://lists.danga.com/pipermail/memcached/2007-

July/004802.html|

9、 我需要把memcached中的item批量导出导入,怎么办?

好吧好吧。如果您需要批量导出导入,最可能的原因一般是重新生成缓存 数据需要消耗很长的时间,或者数据库坏了让您饱受痛苦。

如果一个memcached节点down 了让您很痛苦,那么您还会陷入其他很 多麻烦。您的系统太脆弱了。您需要做一些优化工作。比如处理“惊群’'问 题(比如memcached节点都失效了,反复的查询让您的数据库不堪重负… 这个问题在FAQ的其他提到过),或者优化不好的查询。记住, Memcached并不是您逃避优化查询的借口。

如果您的麻烦仅仅是重新生成缓存数据需要消耗很长时间(15秒到超过5 分钟),您可以考虑重新使用数据库。这里给出一些提示:

•使用MogileFS (或者CouchDB等类似的软件)在存储item。把item计算 出来并dump磁盘上。MogileFS可以很方便地覆写item,并提供快速地 访问。您甚至可以把MogileFS中的item缓存在memcached中,这样可 以加快读取速度。MogileFS+Memcached的组合可以加快缓存不命中时的 响应速度,提高网站的可用性。

•重新使用MySQL。MySQL的InnoDB主键查询的速度非常快。如果大 部分缓存数据都可以放到VARCHAR字段中,那么主键查询的性能将更 好。从memcached中按key查询几乎等价于MySQL的主键查询:将key 哈希到64-bit的整数,然后将数据存储到MySQL中。您可以把原始(不做 哈希)的key存储都普通的字段中,然后建立二级索引来加快查询…key被 动地失效,批量删除失效的key,等等。

•上面的方法都可以引入memcached,在重启memcached的时候仍然 提供很好的性能。由于您不需要当心"hot '‘的item被memcached LRU算 法突然淘汰,用户再也不用花几分钟来等待重新生成缓存数据(当缓存数 据突然从内存中消失时),因此上面的方法可以全面提高性能。

10、 memcached是如何做身份验证的?

没有身份认证机制!memcached是运行在应用下层的软件(身份验证应该是 应用上层的职责)。memcached的客户端和服务器端之所以是轻量级的, 部分原因就是完全没有实现身份验证机制。这样,memcached可以很快 地创建新连接,服务器端也无需任何配置。

如果您希望限制访问,您可以使用防火墙,或者让memcached监听unix

domain socket o

11、 memcached的多线程是什么?如何使用它们?

线程就是定律(threads rule)!在Steven Grimm和Facebook的努力下, memcached 1.2及更高版本拥有了多线程模式。多线程模式允许 memcached能够充分利用多个CPU,并在CPU之间共享所有的缓存数 据。memcached使用一种简单的锁机制来保证数据更新操作的互斥。相 比在同一个物理机器上运行多个memcached实例,这种方式能够更有效 地处理 multi getso

如果您的系统负载并不重,也许您不需要启用多线程工作模式。如果您在 运行一个拥有大规模硬件的、庞大的网站,您将会看到多线程的好处。 简单地总结一下:命令解析(memcached在这里花了大部分时间)可以运行 在多线程模式下。memcached内部对数据的操作是基于很多全局锁的(因 此这部分工作不是多线程的)。未来对多线程模式的改进,将移除大量的全 局锁,提高memcached在负载极高的场景下的性能。

12、 memcached能接受的key的最大长度是多少?

key的最大长度是250个字符。需要注意的是,250是memcached服务 器端内部的限制,如果您使用的客户端支持"key的前缀或类似特性,那 么key(前缀+原始key)的最大长度是可以超过250个字符的。我们推荐使 用使用较短的key,因为可以节省内存和带宽。

13、 memcached对item的过期时间有什么限制?

过期时间最大可以达到30天.memcached把传入的过期时间(时间段)解释 成时间点后,一旦到了这个时间点,memcached就把item置为失效状 态。这是一个简单但obscure的机制。

14、 memcached最大能存储多大的单个item?

1MB。如果你的数据大于1MB,可以考虑在客户端压缩或拆分到多个key 中。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值