Mysql|Redis|Memcached|MongoDB面试题
Mysql|Redis|Memcached|MongoDB面试题
Mysql面试题
1 、数据库存储引擎
数据库存储引擎是数据库底层软件组织,数据库管理系统(DBMS)使用数据引擎进行创建、查询、更新和删除数据。不同的存储引擎提供
不同的存储机制、索引技巧、锁定水平等功能,使用不同的存储引擎,还可以 获得特定的功能。现在许多不同的数据库管理系统都支持多
种不同的数据引擎。存储引擎主要有: 1. MyIsam , 2. InnoDB, 3. Memory, 4. Archive, 5. Federated 。
2 、InnoDB(B+树)
InnoDB 底层存储结构为B+树, B树的每个节点对应innodb的一个page, page大小是固定的,一般设为 16k。其中非叶子节点只有键值,
叶子节点包含完成数据
适用场景:
1 )经常更新的表,适合处理多重并发的更新请求。
2 )支持事务。
3 )可以从灾难中恢复(通过 bin-log 日志等)。
4 )外键约束。只有他支持外键。
5 )支持自动增加列属性 auto_increment。
2 、TokuDB( Fractal Tree-节点带数据)
TokuDB 底层存储结构为 Fractal Tree,Fractal Tree 的结构与 B+树有些类似, 在 Fractal Tree中, 每一个 child 指针除了需要指向一个 child
节点外,还会带有一个 Message Buffer ,这个Message Buffer 是一个 FIFO 的队列,用来缓存更新操作。
例如,一次插入操作只需要落在某节点的 Message Buffer 就可以马上返回了,并不需要搜索到叶子节点。这些缓存的更新会在查询时或后
台异步合并应用到对应的节点中。
TokuDB 在线添加索引,不影响读写操作, 非常快的写入性能, Fractal-tree 在事务实现上有优
势。 他主要适用于访问频率不高的数据或历史数据归档
3 、MyIASM
MyIASM是 MySQL默认的引擎,但是它没有提供对数据库事务的支持,也不支持行级锁和外键,因此当 NSERT(插入)或 UPDATE(更新)数据
时即写操作需要锁定整个表,效率便会低一些。
ISAM 执行读取操作的速度很快,而且不占用大量的内存和存储资源。在设计之初就预想数据组织成有固定长度的记录,按顺序存储的。 ---
ISAM 是一种静态索引结构。
缺点是它不 支持事务处理。
4 、Memory
Memory(也叫 HEAP)堆内存:使用存在内存中的内容来创建表。每个 MEMORY 表只实际对应一个磁盘文件。 MEMORY 类型的表访问
非常得快,因为它的数据是放在内存中的,并且默认使用HASH 索引。但是一旦服务关闭,表中的数据就会丢失掉。 Memory 同时支持散
列索引和 B 树索引, B树索引可以使用部分查询和通配查询,也可以使用<,>和>=等操作符方便数据挖掘,散列索引相等的比较快但是对于
范围的比较慢很多
5 、数据库引擎有哪些
如何查看mysql提供的所有存储引擎
mysql常用引擎包括:MYISAM、Innodb、Memory、MERGE
mysql> show engines;
1. MYISAM:全表锁,拥有较高的执行速度,不支持事务,不支持外键,并发性能差,占用空间相对较小,对事务完整性没有要求,以
select、insert为主的应用基本上可以使用这引擎
- Innodb:行级锁,提供了具有提交、回滚和崩溃回复能力的事务安全,支持自动增长列,支持外键约束,并发能力强,占用空间是
MYISAM的2.5倍,处理效率相对会差一些 - Memory:全表锁,存储在内容中,速度快,但会占用和数据量成正比的内存空间且数据在mysql重启时会丢失,默认使用HASH索引,
检索效率非常高,但不适用于精确查找,主要用于那些内容变化不频繁的代码表 - MERGE:是一组MYISAM表的组合
6 、InnoDB与MyISAM的区别
- InnoDB支持事务,MyISAM不支持,对于InnoDB每一条SQL语言都默认封装成事务,自动提交,这样会影响速度,所以最好把多条
SQL语言放在begin和commit之间,组成一个事务; - InnoDB支持外键,而MyISAM不支持。对一个包含外键的InnoDB表转为MYISAM会失败;
- InnoDB是聚集索引,数据文件是和索引绑在一起的,必须要有主键,通过主键索引效率很高。但是辅助索引需要两次查询,先查询到
主键,然后再通过主键查询到数据。因此,主键不应该过大,因为主键太大,其他索引也都会很大。而MyISAM是非聚集索引,数据文
件是分离的,索引保存的是数据文件的指针。主键索引和辅助索引是独立的。 - InnoDB不保存表的具体行数,执行select count(*) from table时需要全表扫描。而MyISAM用一个变量保存了整个表的行数,执行上
述语句时只需要读出该变量即可,速度很快; - Innodb不支持全文索引,而MyISAM支持全文索引,查询效率上MyISAM要高
7 、索引
索引(Index)是帮助 MySQL 高效获取数据的数据结构。 常见的查询算法,顺序查找,二分查找,二叉排序树查找,哈希散列法,分块查找,平衡多
路搜索树 B 树(B-tree) ,索引是对数据库表中一个或多个列的值进行排序的结构,建立索引有助于快速获取信息。
你也可以这样理解:索引就是加快检索表中数据的方法。数据库的索引类似于书籍的索引。在书籍中,索引允许用户不必翻阅完整个书就能
迅速地找到所需要的信息。在数据库中,索引也允许数据库程序迅速地找到表中的数据,而不必扫描整个数据库
mysql 有 4 种不同的索引:
主键索引(PRIMARY)
唯一索引(UNIQUE)
普通索引(INDEX)
全文索引(FULLTEXT)
索引并非是越多越好,创建索引也需要耗费资源,一是增加了数据库的存储空间,二是在插入和删除时要花费较多的时间维护索引
索引加快数据库的检索速度
索引降低了插入、删除、修改等维护任务的速度
唯一索引可以确保每一行数据的唯一性
通过使用索引,可以在查询的过程中使用优化隐藏器,提高系统的性能
索引需要占物理和数据空间
8 、常见索引原则有
1. 选择唯一性索引,唯一性索引的值是唯一的,可以更快速的通过该索引来确定某条记录。
2. 为经常需要排序、分组和联合操作的字段建立索引。
3. 为常用作为查询条件的字段建立索引。
4. 限制索引的数目:
越多的索引,会使更新表变得很浪费时间。尽量使用数据量少的索引
5. 如果索引的值很长,那么查询的速度会受到影响。尽量使用前缀来索引
6. 如果索引字段的值很长,最好使用值的前缀来索引。
7. 删除不再使用或者很少使用的索引
8. 最左前缀匹配原则,非常重要的原则。
9. 尽量选择区分度高的列作为索引区分度的公式是表示字段不重复的比例
10. 索引列不能参与计算,保持列“干净”:带函数的查询不参与索引。
11. 尽量的扩展索引,不要新建索引
9 、数据库的三范式是什么
第一范式:列不可再分
第二范式:行可以唯一区分,主键约束
第三范式:表的非主属性不能依赖与其他表的非主属性 外键约束
且三大范式是一级一级依赖的,第二范式建立在第一范式上,第三范式建立第一第二范式上 。
10 、第一范式(1st NF - 列都是不可再分)
第一范式的目标是确保每列的原子性:如果每列都是不可再分的最小数据单元(也称为最小的原子单元),则满足第一范式(1NF)
11 、第二范式(2nd NF- 每个表只描述一件事情)
首先满足第一范式,并且表中非主键列不存在对主键的部分依赖。 第二范式要求每个表只描述一件事情。
12 、第三范式(3rd NF- 不存在对非主键列的传递依赖)
第三范式定义是,满足第二范式,并且表中的列不存在对非主键列的传递依赖。 除了主键订单编号外,顾客姓名依赖于非主键顾客编号。
13 、数据库是事务
事务(TRANSACTION)是作为单个逻辑工作单元执行的一系列操作, 这些操作作为一个整体一起向系统提交,要么都执行、要么都不执行 。
事务是一个不可分割的工作逻辑单元事务必须具备以下四个属性,简称 ACID 属性:
原子性(Atomicity)
- 事务是一个完整的操作。事务的各步操作是不可分的(原子的);要么都执行,要么都不执
行。
一致性(Consistency) - 当事务完成时,数据必须处于一致状态。
隔离性(Isolation)
- 对数据进行修改的所有并发事务是彼此隔离的, 这表明事务必须是独立的,它不应以任何方
式依赖于或影响其他事务。
永久性(Durability) - 事务完成后,它对数据库的修改被永久保持,事务日志能够保持事务的永久性
14 、SQL优化
1 、查询语句中不要使用select *
2 、尽量减少子查询,使用关联查询(left join,right join,inner join)替代
3 、减少使用IN或者NOT IN ,使用exists,not exists或者关联查询语句替代
4 、or 的查询尽量用 union或者union all 代替(在确认没有重复数据或者不用剔除重复数据时,union all会更好)
5 、应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。
6 、应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如: select id from t where num
is null 可以在num上设置默认值 0 ,确保表中num列没有null值,然后这样查询: select id from t where num=0
15 、简单说一说drop、delete与truncate的区别
SQL中的drop、delete、truncate都表示删除,但是三者有一些差别
delete和truncate只删除表的数据不删除表的结构
速度,一般来说: drop> truncate >delete
delete语句是dml,这个操作会放到rollback segement中,事务提交之后才生效;
如果有相应的trigger,执行的时候将被触发. truncate,drop是ddl, 操作立即生效,原数据不放到rollbacksegment中,不能回滚. 操作不触发
trigger
16 、什么是视图
视图是一种虚拟的表,具有和物理表相同的功能。可以对视图进行增,改,查,操作,试图通常是有一个表或者多个表的行或列的子集。对
视图的修改不影响基本表。它使得我们获取数据更容易,相比多表查询
17 、什么是内联接、左外联接、右外联接?
内联接(Inner Join):匹配 2 张表中相关联的记录。
左外联接(Left Outer Join):除了匹配 2 张表中相关联的记录外,还会匹配左表中剩余的记录,右表中未匹配到的字段用NULL表示。
右外联接(Right Outer Join):除了匹配 2 张表中相关联的记录外,还会匹配右表中剩余的记录,左表中未匹配到的字段用NULL表示。在
判定左表和右表时,要根据表名出现在Outer Join的左右位置关系
18 、并发事务带来哪些问题?
在典型的应用程序中,多个事务并发运行,经常会操作相同的数据来完成各自的任务(多个用户对同一
数据进行操作)。并发虽然是必须的,但可能会导致以下的问题。
脏读(Dirty read): 当一个事务正在访问数据并且对数据进行了修改,而这种修改还没有提交到数据库中,这时另外一个事务也访问了这
个数据,然后使用了这个数据。因为这个数据是还没有提交的数据,那么另外一个事务读到的这个数据是“脏数据”,依据“脏数据”所做的操
作可能是不正确的。
丢失修改(Lost to modify): 指在一个事务读取一个数据时,另外一个事务也访问了该数据,那么在第一个事务中修改了这个数据后,第
二个事务也修改了这个数据。这样第一个事务内的修改结果就被丢失,因此称为丢失修。 例如:事务 1 读取某表中的数据A=20,事务 2 也读
取A=20,事务 1 修改A=A-1,事务 2 也修改A=A-1,最终结果A=19,事务 1 的修改被丢失。
不可重复读(Unrepeatableread): 指在一个事务内多次读同一数据。在这个事务还没有结束时,另一个事务也访问该数据。那么,在第
一个事务中的两次读数据之间,由于第二个事务的修改导致第一个事务两次读取的数据可能不太一样。这就发生了在一个事务内两次读到的
数据是不一样的情况,因此称为不可重复读。
幻读(Phantom read): 幻读与不可重复读类似。它发生在一个事务(T1)读取了几行数据,接着另一个并发事务(T2)插入了一些数据
时。在随后的查询中,第一个事务(T1)就会发现多了一些原本不存在的记录,就好像发生了幻觉一样,所以称为幻读。
不可重复读和幻读区别:
不可重复读的重点是修改比如多次读取一条记录发现其中某些列的值被修改,幻读的重点在于新增或者删除比如多次读取一条记录发现记录
增多或减少了
19 、事务隔离级别有哪些?MySQL的默认隔离级别是?
SQL 标准定义了四个隔离级别:
READ-UNCOMMITTED(读取未提交): 最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读。
READ-COMMITTED(读取已提交): 允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生。
REPEATABLE-READ(可重复读): 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复
读,但幻读仍有可能发生
SERIALIZABLE(可串行化): 最高的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干
扰,也就是说,该级别可以防止脏读、不可重复读以及幻读
MySQL InnoDB 存储引擎的默认支持的隔离级别是 REPEATABLE-READ(可重读)。我们可以通过
SELECT @@tx_isolation; 命令来查看
这里需要注意的是:与 SQL 标准不同的地方在于 InnoDB 存储引擎在 REPEATABLE-READ(可重读)事务隔离级别下使用的是Next-Key
Lock 锁算法,因此可以避免幻读的产生,这与其他数据库系统(如SQL Server) 是不同的。所以说InnoDB 存储引擎的默认支持的隔离级别是
REPEATABLE-READ(可重读) 已经可以完全保证事务的隔离性要求,即达到了 SQL标准的 SERIALIZABLE(可串行化) 隔离级别。因为隔离
级别越低,事务请求的锁越少,所以大部分数据库系统的隔离级别都是 READCOMMITTED(读取提交内容) ,但是你要知道的是InnoDB 存
储引擎默认使用 REPEAaTABLEREAD(可重读) 并不会有任何性能损失
InnoDB 存储引擎在 分布式事务 的情况下一般会用到 SERIALIZABLE(可串行化) 隔离级别。
20 、大表如何优化?
当MySQL单表记录数过大时,数据库的CRUD性能会明显下降,一些常见的优化措施如下:
限定数据的范围
务必禁止不带任何限制数据范围条件的查询语句。比如:我们当用户在查询订单历史的时候,我们可以控制在一个月的范围内;
读/写分离
经典的数据库拆分方案,主库负责写,从库负责读;
垂直分区
根据数据库里面数据表的相关性进行拆分。 例如,用户表中既有用户的登录信息又有用户的基本信息,可以将用户表拆分成两个单独的
表,甚至放到单独的库做分库。
简单来说垂直拆分是指数据表列的拆分,把一张列比较多的表拆分为多张表。 如下图所示,这样来说大家应该就更容易理解了
垂直拆分的优点: 可以使得列数据变小,在查询时减少读取的Block数,减少I/O次数。此外,垂
直分区可以简化表的结构,易于维护。
垂直拆分的缺点: 主键会出现冗余,需要管理冗余列,并会引起Join操作,可以通过在应用层进行
Join来解决。此外,垂直分区会让事务变得更加复杂;
21 、水平分区
保持数据表结构不变,通过某种策略存储数据分片。这样每一片数据分散到不同的表或者库中,达到了分布式的目的。 水平拆分可以支撑
非常大的数据量。
水平拆分是指数据表行的拆分,表的行数超过 200 万行时,就会变慢,这时可以把一张的表的数据拆成多张表来存放。举个例子:我们可以
将用户信息表拆分成多个用户信息表,这样就可以避免单一表数据量过大对性能造成影响。
水平拆分可以支持非常大的数据量。需要注意的一点是:分表仅仅是解决了单一表数据过大的问题,但由于表的数据还是在同一台机器上,
其实对于提升MySQL并发能力没有什么意义,所以 水平拆分最好分库 。
mysql> SELECT @@tx_isolation;
+-----------------+
| @@tx_isolation |
+-----------------+
| REPEATABLE-READ |
+-----------------+
水平拆分能够 支持非常大的数据量存储,应用端改造也少,但 分片事务难以解决 ,跨节点Join性能较差,逻辑复杂。《Java工程师修炼之
道》的作者推荐 尽量不要对数据进行分片,因为拆分会带来逻辑、部署、运维的各种复杂度 ,一般的数据表在优化得当的情况下支撑千万
以下的数据量是没有太大问题的。如果实在要分片,尽量选择客户端分片架构,这样可以减少一次和中间件的网络I/O。
- 下面补充一下数据库分片的两种常见方案:
客户端代理: 分片逻辑在应用端,封装在jar包中,通过修改或者封装JDBC层来实现。 当当网的Sharding-JDBC 、阿里的TDDL是两种
比较常用的实现。 - 中间件代理: 在应用和数据中间加了一个代理层。分片逻辑统一维护在中间件服务中。 我们现在谈的 Mycat 、 360 的Atlas、网易的
DDB等等都是这种架构的实现。
详细内容可以参考: MySQL大表优化方案: https://segmentfault.com/a/1190000006158186
22 、分库分表之后,id 主键如何处理
因为要是分成多个表之后,每个表都是从 1 开始累加,这样是不对的,我们需要一个全局唯一的 id 来支持。
生成全局 id 有下面这几种方式:
UUID: 不适合作为主键,因为太长了,并且无序不可读,查询效率低。比较适合用于生成唯一的名字的标示比如文件的名字。
数据库自增 id : 两台数据库分别设置不同步长,生成不重复ID的策略来实现高可用。这种方式生成的 id 有序,但是需要独立部署数据库实
例,成本高,还会有性能瓶颈。
利用 redis 生成 id : 性能比较好,灵活方便,不依赖于数据库。但是,引入了新的组件造成系统更加复杂,可用性降低,编码更加复杂,增
加了系统成本。
Twitter的snowflake算法 : Github 地址:https://github.com/twitter-archive/snowflake。
美团的Leaf分布式ID生成系统 : Leaf 是美团开源的分布式ID生成器,能保证全局唯一性、趋势递增、单调递增、信息安全,里面也提到了
几种分布式方案的对比,但也需要依赖关系数据库、Zookeeper等中间件。感觉还不错。美团技术团队的一篇文章:https://tech.meituan.
com/2017/04/21/mt-leaf.html
23 、存储过程(特定功能的 SQL 语句集)
一组为了完成特定功能的 SQL 语句集,存储在数据库中,经过第一次编译后再次调用不需要再次编译,用户通过指定存储过程的名字并给
出参数(如果该存储过程带有参数)来执行它。存储过程是数据库中的一个重要对象。
24 、存储过程优化思路
- 尽量利用一些 sql 语句来替代一些小循环,例如聚合函数,求平均函数等。
- 中间结果存放于临时表,加索引。
- 少使用游标。 sql 是个集合语言,对于集合运算具有较高性能。而 cursors 是过程运算。比如对一个 100 万行的数据进行查询。游标
需要读表 100 万次,而不使用游标则只需要少量几次读取。 - 事务越短越好。 sqlserver 支持并发操作。如果事务过多过长,或者隔离级别过高,都会造成并发操作的阻塞,死锁。导致查询极慢,
cpu 占用率极地。 - 使用 try-catch 处理错误异常。
- 查找语句尽量不要放在循环内
25 、触发器(一段能自动执行的程序)
触发器是一段能自动执行的程序,是一种特殊的存储过程, 触发器和普通的存储过程的区别是:触发器是当对某一个表进行操作时触发。
诸如: update、 insert、 delete 这些操作的时候,系统会自动调用执行该表上对应的触发器。 SQL Server 2005 中触发器可以分为两类:
DML 触发器和DDL 触发器,其中 DDL 触发器它们会影响多种数据定义语言语句而激发,这些语句有 create、alter、 drop 语句。
26 、数据库并发策略
并发控制一般采用三种方法,分别是乐观锁和悲观锁以及时间戳。
27 、MySQL 中有哪几种锁?
1 、表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。
2 、行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。
3 、页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般
28 、MySQL 中有哪些不同的表格?
共有 5 种类型的表格:
1 、MyISAM
2 、Heap
3 、Merge
4 、INNODB
5 、ISAM
29 、简述在 MySQL 数据库中 MyISAM 和 InnoDB 的区别
MyISAM:
不支持事务,但是每次查询都是原子的;
支持表级锁,即每次操作是对整个表加锁;
存储表的总行数;
一个 MYISAM 表有三个文件:索引文件、表结构文件、数据文件;
采用菲聚集索引,索引文件的数据域存储指向数据文件的指针。辅索引与主索引
基本一致,但是辅索引不用保证唯一性。
InnoDb:
支持 ACID 的事务,支持事务的四种隔离级别;
支持行级锁及外键约束:因此可以支持写并发;
不存储总行数:
一个 InnoDb 引擎存储在一个文件空间(共享表空间,表大小不受操作系统控制,一个表可能分布在多个文件里),也有可能为多个(设置
为独立表空,表大小受操作系统文件大小限制,一般为 2G),受操作系统文件大小的限制;
主键索引采用聚集索引(索引的数据域存储数据文件本身),辅索引的数据域存储主键的值;因此从辅索引查找数据,需要先通过辅索引找
到主键值,再访问辅索引;最好使用自增主键,防止插入数据时,为维持 B+树结构,文件的大调整。
30 、MySQL 中 InnoDB 支持的四种事务隔离级别名称,以及逐级之间的区别?
SQL 标准定义的四个隔离级别为:
1 、read uncommited :读到未提交数据
2 、read committed:脏读,不可重复读
3 、repeatable read:可重读
4 、serializable :串行事物
31 、CHAR 和 VARCHAR 的区别?
1 、CHAR 和 VARCHAR 类型在存储和检索方面有所不同
2 、CHAR 列长度固定为创建表时声明的长度,长度值范围是 1 到 255 当 CHAR值被存储时,它们被用空格填充到特定长度,检索 CHAR 值
时需删除尾随空格。
32 、主键和候选键有什么区别?
表格的每一行都由主键唯一标识,一个表只有一个主键。
主键也是候选键。按照惯例,候选键可以被指定为主键,并且可以用于任何外键
引用。
33 、myisamchk 是用来做什么的?
它用来压缩 MyISAM 表,这减少了磁盘或内存使用。
34 、MyISAM Static 和 MyISAM Dynamic 有什么区别?
在 MyISAM Static 上的所有字段有固定宽度。动态 MyISAM 表将具有像 TEXT,BLOB 等字段,以适应不同长度的数据类型。
MyISAM Static 在受损情况下更容易恢复。
35 、如果一个表有一列定义为 TIMESTAMP,将发生什么?
每当行被更改时,时间戳字段将获取当前时间戳。
列设置为 AUTO INCREMENT 时,如果在表中达到最大值,会发生什么情况?
它会停止递增,任何进一步的插入都将产生错误,因为密钥已被使用。
怎样才能找出最后一次插入时分配了哪个自动增量?
LAST_INSERT_ID 将返回由 Auto_increment 分配的最后一个值,并且不需要指定表名称
36 、你怎么看到为表格定义的所有索引?
索引是通过以下方式为表格定义的:
37 、LIKE 声明中的%和_是什么意思?
SHOW INDEX FROM <tablename>;
%对应于 0 个或更多字符,_只是 LIKE 语句中的一个字符
如何在 Unix 和 MySQL 时间戳之间进行转换?
UNIX_TIMESTAMP 是从 MySQL 时间戳转换为 Unix 时间戳的命令
FROM_UNIXTIME 是从 Unix 时间戳转换为 MySQL 时间戳的命令
38 、列对比运算符是什么?
在 SELECT 语句的列比较中使用=,<>,<=,<,> =,>,<<,>>,<=>,AND,OR 或 LIKE 运算符。
39 、BLOB 和 TEXT 有什么区别?
BLOB 是一个二进制对象,可以容纳可变数量的数据。TEXT 是一个不区分大小写
的 BLOB。
BLOB 和 TEXT 类型之间的唯一区别在于对 BLOB 值进行排序和比较时区分大小
写,对 TEXT 值不区分大小写。
40 、MySQL_fetch_array 和 MySQL_fetch_object 的区别是什么?
以下是 MySQL_fetch_array 和 MySQL_fetch_object 的区别:
MySQL_fetch_array() – 将结果行作为关联数组或来自数据库的常规数组返回。
MySQL_fetch_object – 从数据库返回结果行作为对象。
41 、MyISAM 表格将在哪里存储,并且还提供其存储格式?
每个 MyISAM 表格以三种格式存储在磁盘上:
·“.frm”文件存储表定义
·数据文件具有“.MYD”(MYData)扩展名
索引文件具有“.MYI”(MYIndex)扩展名
42 、MySQL 如何优化 DISTINCT?
DISTINCT 在所有列上转换为 GROUP BY,并与 ORDER BY 子句结合使用。
SELECT DISTINCT t1.a FROM t1,t2 where t1.a=t2.a;
43 、如何显示前 50 行?
在 MySQL 中,使用以下代码查询显示前 50 行:
44 、可以使用多少列创建索引?
任何标准表最多可以创建 16 个索引列 。
45 、NOW()和 CURRENT_DATE()有什么区别?
NOW()命令用于显示当前年份,月份,日期,小时,分钟和秒。
CURRENT_DATE()仅显示当前年份,月份和日期。
46 、什么是非标准字符串类型?
1 、TINYTEXT
2 、TEXT
3 、MEDIUMTEXT
4 、LONGTEXT
47 、什么是通用 SQL 函数?
1 、CONCAT(A, B) – 连接两个字符串值以创建单个字符串输出。通常用于将两个或多个字段合并为一个字段。
SELECT*FROM LIMIT 0,50;
2 、FORMAT(X, D)- 格式化数字 X 到 D 有效数字。
3 、CURRDATE(), CURRTIME()- 返回当前日期或时间。
4 、NOW() – 将当前日期和时间作为一个值返回。
5 、MONTH(),DAY(),YEAR(),WEEK(),WEEKDAY() – 从日期值中提取给定数据。
6 、HOUR(),MINUTE(),SECOND() – 从时间值中提取给定数据。
7 、DATEDIFF(A,B) – 确定两个日期之间的差异,通常用于计算年龄
8 、SUBTIMES(A,B) – 确定两次之间的差异。
9 、FROMDAYS(INT) – 将整数天数转换为日期值
48 、MySQL 支持事务吗?
在缺省模式下,MySQL 是 autocommit 模式的,所有的数据库更新操作都会即时提交,所以在缺省情况下,MySQL 是不支持事务的。
但是如果你的 MySQL 表类型是使用 InnoDB Tables 或 BDB tables 的话,你的MySQL 就可以使用事务处理,使用 SET AUTOCOMMIT=0 就
可以使 MySQL 允许在非 autocommit 模式,在非autocommit 模式下,你必须使用 COMMIT 来提交你的更改,或者用 ROLLBACK来回滚
你的更改。
49 、MySQL 里记录货币用什么字段类型好
NUMERIC 和 DECIMAL 类型被 MySQL 实现为同样的类型,这在 SQL92 标准允许。他们被用于保存值,该值的准确精度是极其重要的值,
例如与金钱有关的数据。当声明一个类是这些类型之一时,精度和规模的能被(并且通常是)指定。
例如:
在这个例子中,9(precision)代表将被用于存储值的总的小数位数,而 2(scale)代表将被用于存储小数点后的位数。因此,在这种情况下,能
被存储在 salary 列中的值的范围是从-9999999.99 到
9999999.99。
在这个例子中,9(precision)代表将被用于存储值的总的小数位数,而 2(scale)代表将被用于存储小数点后的位数。因此,在这种情况下,能
被存储在 salary 列中的值的范围是从-9999999.99 到
9999999.99。
50 、MySQL 有关权限的表都有哪几个?
MySQL 服务器通过权限表来控制用户对数据库的访问,权限表存放在 MySQL 数据库里,由 MySQL_install_db 脚本初始化。这些权限表分
别 user,db,table_priv,columns_priv 和 host。
51 、列的字符串类型可以是什么?
字符串类型是:
1 、SET
2 、BLOB
3 、ENUM
4 、CHAR
5 、TEXT
52 、MySQL 数据库作发布系统的存储,一天五万条以上的增量,预计运维三年,怎么优化?
1 、设计良好的数据库结构,允许部分数据冗余,尽量避免 join 查询,提高效率。
2 、选择合适的表字段数据类型和存储引擎,适当的添加索引。
3 、MySQL 库主从读写分离。
4 、找规律分表,减少单表中的数据量提高查询速度。
5 、添加缓存机制,比如 memcached,apc 等。
6 、不经常改动的页面,生成静态页面。
7 、书写高效率的 SQL。比如 SELECT * FROM TABEL 改为 SELECT field_1,field_2, field_3 FROM TABLE.
53 、锁的优化策略
1 、读写分离
2 、分段加锁
3 、减少锁持有的时间
4.多个线程尽量以相同的顺序去获取资源不能将锁的粒度过于细化,不然可能会出现线程的加锁和释放次数过多,反而效率不如一次加一把
大锁。
54 、索引的底层实现原理和优化
B+树,经过优化的 B+树
主要是在所有的叶子结点中增加了指向下一个叶子节点的指针,因此 InnoDB 建议为大部分表使用默认自增的主键作为主索引。
salary DECIMAL(9,2)
55 、什么情况下设置了索引但无法使用
1 、以“%”开头的 LIKE 语句,模糊匹配
2 、OR 语句前后没有同时使用索引
3 、数据类型出现隐式转化(如 varchar 不加单引号的话可能会自动转换为 int 型)
56 、实践中如何优化 MySQL
最好是按照以下顺序优化:
1 、SQL 语句及索引的优化
2 、数据库表结构的优化
3 、系统配置的优化
4 、硬件的优化
详细可以查看 阿里 P8 架构师谈:MySQL 慢查询优化、索引优化、以及表等优化总结
57 、优化数据库的方法
1 、选取最适用的字段属性,尽可能减少定义字段宽度,尽量把字段设置 NOTNULL,例如’省份’、’性别’最好适用 ENUM
2 、使用连接(JOIN)来代替子查询
3 、适用联合(UNION)来代替手动创建的临时表
4 、事务处理
5 、锁定表、优化事务处理
6 、适用外键,优化锁定表
7 、建立索引
8 、优化查询语句
58 、简单描述 MySQL 中,索引,主键,唯一索引,联合索引的区别,对数据库的性能有什
么影响(从读写两方面)
索引是一种特殊的文件(InnoDB 数据表上的索引是表空间的一个组成部分),它们包含着对数据表里所有记录的引用指针。
普通索引(由关键字 KEY 或 INDEX 定义的索引)的唯一任务是加快对数据的访问速度。
普通索引允许被索引的数据列包含重复的值。如果能确定某个数据列将只包含彼此各不相同的值,在为这个数据列创建索引的时候就应该用
关键字 UNIQUE 把它定义为一个唯一索引。也就是说,唯一索引可以保证数据记录的唯一性。
主键,是一种特殊的唯一索引,在一张表中只能定义一个主键索引,主键用于唯一标识一条记录,使用关键字 PRIMARY KEY 来创建。
索引可以覆盖多个数据列,如像 INDEX(columnA, columnB)索引,这就是联合索引。
索引可以极大的提高数据的查询速度,但是会降低插入、删除、更新表的速度,因为在执行这些写操作时,还要操作索引文件
59 、数据库中的事务是什么?
事务(transaction)是作为一个单元的一组有序的数据库操作。如果组中的所有操作都成功,则认为事务成功,即使只有一个操作失败,
事务也不成功。如果所有操作完成,事务则提交,其修改将作用于所有其他数据库进程。如果一个操作失败,则事务将回滚,该事务所有操
作的影响都将取消。
事务特性:
1 、原子性:即不可分割性,事务要么全部被执行,要么就全部不被执行。
2 、一致性或可串性。事务的执行使得数据库从一种正确状态转换成另一种正确状态
3 、隔离性。在事务正确提交之前,不允许把该事务对数据的任何改变提供给任何其他事物
4 、持久性。事务正确提交后,其结果将永久保存在数据库中,即使在事务提交后有了其他故障,事务的处理结果也会得到保存。
或者这样理解:
事务就是被绑定在一起作为一个逻辑工作单元的 SQL 语句分组,如果任何一个语句操作失败那么整个操作就被失败,以后操作就会回滚到
操作前状态,或者是上有个节点。为了确保要么执行,要么不执行,就可以使用事务。要将有组语句作为事务考虑,就需要通过 ACID 测
试,即原子性,一致性,隔离性和持久性。
60 、SQL 注入漏洞产生的原因?如何防止?
SQL 注入产生的原因:程序开发过程中不注意规范书写 sql 语句和对特殊字符进行过滤,导致客户端可以通过全局变量 POST 和 GET 提交
一些 sql 语句正常执行。
防止 SQL 注入的方式:
开启配置文件中的 magic_quotes_gpc 和 magic_quotes_runtime 设置 执行 sql 语句时使用 addslashes 进行 sql 语句转换
Sql 语句书写尽量不要省略双引号和单引号。
过滤掉 sql 语句中的一些关键词:update、insert、delete、select、 * 。
提高数据库表和字段的命名技巧,对一些重要的字段根据程序的特点命名,取不易被猜到的。
61 、为表中得字段选择合适得数据类型
字段类型优先级: 整形>date,time>enum,char>varchar>blob,text优先考虑数字类型,其次是日期或者二进制类型,最后是字符串类型,同
级别得数据类型,应该优先选择占用空间小的数据类型
62 、存储时期
Datatime: 以 YYYY-MM-DD HH:MM:SS 格式存储时期时间,精确到秒,占用 8 个字节得存储空间,datatime 类型与时区无关
Timestamp: 以时间戳格式存储,占用 4 个字节,范围小 1970-1-1 到 2038-1-19,显示依赖于所指定得时区,默认在第一个列行的数据修
改时可以自动得修改
timestamp 列得值
Date:(生日)占用得字节数比使用字符串.datatime.int 储存要少,使用 date 只需要 3 个字节,存储日期月份,还可以利用日期时间函数
进行日期间得计算
Time:存储时间部分得数据
注意:不要使用字符串类型来存储日期时间数据(通常比字符串占用得储存空间小,在进行查找过滤可以利用日期得函数)
使用 int 存储日期时间不如使用 timestamp 类型
63 、对于关系型数据库而言,索引是相当重要的概念,请回答有关索引的几个问题
1 、索引的目的是什么?
快速访问数据表中的特定信息,提高检索速度
创建唯一性索引,保证数据库表中每一行数据的唯一性。
加速表和表之间的连接
使用分组和排序子句进行数据检索时,可以显著减少查询中分组和排序的时间
2 、索引对数据库系统的负面影响是什么?
负面影响:
创建索引和维护索引需要耗费时间,这个时间随着数据量的增加而增加;索引需要占用物理空间,不光是表需要占用数据空间,每个索引也
需要占用物理空间;当对表进行增、删、改、的时候索引也要动态维护,这样就降低了数据的维护速度。
3 、为数据表建立索引的原则有哪些?
在最频繁使用的、用以缩小查询范围的字段上建立索引。
在频繁使用的、需要排序的字段上建立索引
4 、什么情况下不宜建立索引?
对于查询中很少涉及的列或者重复值比较多的列,不宜建立索引。
对于一些特殊的数据类型,不宜建立索引,比如文本字段(text)等
64 、解释 MySQL 外连接、内连接与自连接的区别
先说什么是交叉连接: 交叉连接又叫笛卡尔积,它是指不使用任何条件,直接将一个表的所有记录和另一个表中的所有记录一一匹配。
内连接 则是只有条件的交叉连接,根据某个条件筛选出符合条件的记录,不符合条件的记录不会出现在结果集中,即内连接只连接匹配的
行。
外连接 其结果集中不仅包含符合连接条件的行,而且还会包括左表、右表或两个表中的所有数据行,这三种情况依次称之为左外连接,右
外连接,和全外连接。
左外连接,也称左连接,左表为主表,左表中的所有记录都会出现在结果集中,对于那些在右表中并没有匹配的记录,仍然要显示,右边对
应的那些字段值以NULL 来填充。右外连接,也称右连接,右表为主表,右表中的所有记录都会出现在结果集中。左连接和右连接可以互
换,MySQL 目前还不支持全外连接。
65 、Myql 中的事务回滚机制概述
事务是用户定义的一个数据库操作序列,这些操作要么全做要么全不做,是一个不可分割的工作单位,事务回滚是指将该事务已经完成的对
数据库的更新操作撤销。
要同时修改数据库中两个不同表时,如果它们不是一个事务的话,当第一个表修改完,可能第二个表修改过程中出现了异常而没能修改,此
时就只有第二个表依旧是未修改之前的状态,而第一个表已经被修改完毕。而当你把它们设定为一个事务的时候,当第一个表修改完,第二
表修改出现异常而没能修改,第一个表和第二个表都要回到未修改的状态,这就是所谓的事务回滚
66 、SQL 语言包括哪几部分?每部分都有哪些操作关键
SQL 语言包括数据定义(DDL)、数据操纵(DML),数据控制(DCL)和数据查询(DQL)四个部分。
数据定义:Create Table,Alter Table,Drop Table, Craete/Drop Index 等
数据操纵:Select ,insert,update,delete,
数据控制:grant,revoke
数据查询:select
67 、完整性约束包括哪些?
数据完整性(Data Integrity)是指数据的精确(Accuracy)和可靠性(Reliability)。
分为以下四类:
1 、实体完整性:规定表的每一行在表中是惟一的实体。
2 、域完整性:是指表中的列必须满足某种特定的数据类型约束,其中约束又包括取值范围、精度等规定。
3 、参照完整性:是指两个表的主关键字和外关键字的数据应一致,保证了表之间的数据的一致性,防止了数据丢失或无意义的数据在数据
库中扩散。
4 、用户定义的完整性:不同的关系数据库系统根据其应用环境的不同,往往还需要一些特殊的约束条件。用户定义的完整性即是针对某个
特定关系数据库的约束条件,它反映某一具体应用必须满足的语义要求。与表有关的约束:包括列约束(NOT NULL(非空约束))和表约束
(PRIMARY KEY、foreign key、check、UNIQUE) 。
68 、什么是锁?
答:数据库是一个多用户使用的共享资源。当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据的情况。若对并
发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性。
加锁是实现数据库并发控制的一个非常重要的技术。当事务在对某个数据对象进行操作前,先向系统发出请求,对其加锁。加锁后事务就对
该数据对象有了一定的控制,在该事务释放锁之前,其他的事务不能对此数据对象进行更新操作。
基本锁类型:锁包括行级锁和表级锁
69 、什么叫视图?游标是什么?
视图是一种虚拟的表,具有和物理表相同的功能。可以对视图进行增,改,查,操作,视图通常是有一个表或者多个表的行或列的子集。对
视图的修改不影响基本表。它使得我们获取数据更容易,相比多表查询。
游标:是对查询出来的结果集作为一个单元来有效的处理。游标可以定在该单元中的特定行,从结果集的当前行检索一行或多行。可以对结
果集当前行做修改。一般不使用游标,但是需要逐条处理数据的时候,游标显得十分重要。
70 、什么是存储过程?用什么来调用?
答:存储过程是一个预编译的 SQL 语句,优点是允许模块化的设计,就是说只需创建一次,以后在该程序中就可以调用多次。如果某次操
作需要执行多次 SQL,使用存储过程比单纯 SQL 语句执行要快。可以用一个命令对象来调用存储过程。
71 、如何通俗地理解三个范式?
第一范式:1NF 是对属性的原子性约束,要求属性具有原子性,不可再分解;
第二范式:2NF 是对记录的惟一性约束,要求记录有惟一标识,即实体的惟一性;
第三范式:3NF 是对字段冗余性的约束,即任何字段不能由其他字段派生出来,它要求字段没有冗余。
范式化设计优缺点:
优点:
可以尽量得减少数据冗余,使得更新快,体积小
缺点:对于查询需要多个表进行关联,减少写得效率增加读得效率,更难进行索引
优化
反范式化:
优点:可以减少表得关联,可以更好得进行索引优化
缺点:数据冗余以及数据异常,数据得修改需要更多的成本
72 、什么是基本表?什么是视图?
答:基本表是本身独立存在的表,在 SQL 中一个关系就对应一个表。 视图是从一个或几个基本表导出的表。视图本身不独立存储在数据库
中,是一个虚表
73 、试述视图的优点?
(1) 视图能够简化用户的操作
(2) 视图使用户能以多种角度看待同一数据;
(3) 视图为数据库提供了一定程度的逻辑独立性;
(4) 视图能够对机密数据提供安全保护
74 、NULL 是什么意思
NULL 这个值表示 UNKNOWN(未知):它不表示“”(空字符串)。对 NULL 这个值的任何比较都会生产一个 NULL 值。您不能把任何值与一个
NULL 值进行比较,并在逻辑上希望获得一个答案。使用 IS NULL 来进行 NULL 判断
75 、主键、外键和索引的区别?
主键、外键和索引的区别
定义 :
主键–唯一标识一条记录,不能有重复的,不允许为空
外键–表的外键是另一表的主键, 外键可以有重复的, 可以是空值
索引–该字段没有重复值,但可以有一个空值
作用:
主键–用来保证数据完整性
外键–用来和其他表建立联系用的
索引–是提高查询排序的速度
个数:
主键–主键只能有一个
外键–一个表可以有多个外键
索引–一个表可以有多个唯一索引
76 、你可以用什么来确保表格里的字段只接受特定范围里的值?
Check 限制,它在数据库表格里被定义,用来限制输入该列的值。触发器也可以被用来限制数据库表格里的字段能够接受的值,但是这种办
法要求触发器在表格里被定义,这可能会在某些情况下影响到性能。
77 、说说对 SQL 语句优化有哪些方法?(选择几条)
1 、Where 子句中:where 表之间的连接必须写在其他 Where 条件之前,那些可以过滤掉最大数量记录的条件必须写在 Where 子句的末
尾.HAVING 最后。
2 、用 EXISTS 替代 IN、用 NOT EXISTS 替代 NOT IN。
3 、 避免在索引列上使用计算
4 、避免在索引列上使用 IS NULL 和 IS NOT NULL
5 、对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。
6 、应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描
7 、应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描
78 、什么是乐观锁
乐观锁认为一个用户读数据的时候,别人不会去写自己所读的数据;悲观锁就刚好相反,觉得自己读数据库的时候,别人可能刚好在写自己
刚读的数据,其实就是持一种比较保守的态度;时间戳就是不加锁,通过时间戳来控制并发出现的问题。
79 、什么是悲观锁
悲观锁就是在读取数据的时候,为了不让别人修改自己读取的数据,就会先对自己读取的数据加锁,只有自己把数据读完了,才允许别人修
改那部分数据,或者反过来说,就是自己修改某条数据的时候,不允许别人读取该数据,只有等自己的整个事务提交了,才释放自己加上的
锁,才允许其他用户访问那部分数据。
80 、什么是时间戳
时间戳就是在数据库表中单独加一列时间戳,比如“TimeStamp”, 每次读出来的时候,把该字段也读出来,当写回去的时候,把该字段加
1 ,提交之前 ,跟数据库的该字段比较一次,如果比数据库的值大的话,就允许保存,否则不允许保存,这种处理方法虽然不使用数据库系
统提供的锁机制,但是这种方法可以大大提高数据库处理的并发量,以上悲观锁所说的加“锁”,其实分为几种锁,分别是: 排它锁(写锁)
和共享锁(读锁) 。
81 、什么是行级锁
行级锁是一种排他锁,防止其他事务修改此行;在使用以下语句时, Oracle 会自动应用行级锁:
- INSERT、 UPDATE、 DELETE、 SELECT ... FOR UPDATE [OF columns] [WAIT n | NOWAIT];
- SELECT ... FOR UPDATE 语句允许用户一次锁定多条记录进行更新
- 使用 COMMIT 或 ROLLBACK 语句释放锁。
82 、什么是表级锁
表示对当前操作的整张表加锁,它实现简单,资源消耗较少,被大部分 MySQL 引擎支持。最常使用的 MYISAM 与 INNODB 都支持表级锁
定。表级锁定分为表共享读锁(共享锁)与表独占写锁(排他锁)。
83 、什么是页级锁
页级锁是 MySQL 中锁定粒度介于行级锁和表级锁中间的一种锁。表级锁速度快,但冲突多,行级冲突少,但速度慢。所以取了折衷的页
级,一次锁定相邻的一组记录。 BDB 支持页级锁
Redis面试题
1 、什么是 Redis?
Redis 是完全开源免费的,遵守 BSD 协议,是一个高性能的 key-value 数据库。
Redis 与其他 key - value 缓存产品有以下三个特点:
Redis 支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。
Redis 不仅仅支持简单的 key-value 类型的数据,同时还提供 list,set,zset,hash 等数据结构的存储。
Redis 支持数据的备份,即 master-slave 模式的数据备份。
Redis 优势
性能极高 – Redis 能读的速度是 110000 次/s,写的速度是 81000 次/s 。丰富的数据类型 – Redis 支持二进制案例的 Strings, Lists, Hashes,
Sets 及Ordered Sets 数据类型操作。
原子 – Redis 的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子
性,通过 MULTI 和 EXEC指令包起来。
丰富的特性 – Redis 还支持 publish/subscribe, 通知, key 过期等等特性。
2 、Redis 与其他 key-value 存储有什么不同?
Redis 有着更为复杂的数据结构并且提供对他们的原子性操作,这是一个不同于其他数据库的进化路径。Redis 的数据类型都是基于基本数
据结构的同时对程序员透明,无需进行额外的抽象。Redis 运行在内存中但是可以持久化到磁盘,所以在对不同数据集进行高速读写时需要
权衡内存,因为数据量不能大于硬件内存。在内存数据库方面的另一个优点是,相比在磁盘上相同的复杂的数据结构,在内存中操作起来非
常简单,这样 Redis可以做很多内部复杂性很强的事情。同时,在磁盘格式方面他们是紧凑的以追加的方式产生的,因为他们并不需要进行
随机访问。
3 、Redis 的数据类型?
Redis 支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及 zsetsorted set:有序集合)。
我们实际项目中比较常用的是 string,hash 如果你是 Redis 中高级用户,还需要加上下面几种数据结构 HyperLogLog、Geo、Pub/Sub。
如果你说还玩过 Redis Module,像 BloomFilter,RedisSearch,Redis-ML,面试官得眼睛就开始发亮了。
4 、使用 Redis 有哪些好处?
1 、速度快,因为数据存在内存中,类似于 HashMap,HashMap 的优势就是查找和操作的时间复杂度都是 O1)
2 、支持丰富数据类型,支持 string,list,set,Zset,hash 等
3 、支持事务,操作都是原子性,所谓的原子性就是对数据的更改要么全部执行,要么全部不执行
4 、丰富的特性:可用于缓存,消息,按 key 设置过期时间,过期后将会自动删除
5 、Redis 相比 Memcached 有哪些优势?
1 、Memcached 所有的值均是简单的字符串,redis 作为其替代者,支持更为丰富的数据类
2 、Redis 的速度比 Memcached 快很
3 、Redis 可以持久化其数据
6 、Memcache 与 Redis 的区别都有哪些?
1 、存储方式 Memecache 把数据全部存在内存之中,断电后会挂掉,数据不能超过内存大小。 Redis 有部份存在硬盘上,这样能保证数据
的持久性。
2 、数据支持类型 Memcache 对数据类型支持相对简单。 Redis 有复杂的数据类型。
3 、使用底层模型不同 它们之间底层实现方式 以及与客户端之间通信的应用协议不一样。 Redis 直接自己构建了 VM 机制 ,因为一般的系
统调用系统函数的话,会浪费一定的时间去移动和请求。
7 、Redis 是单进程单线程的?
Redis 是单进程单线程的,redis 利用队列技术将并发访问变为串行访问,消除了传统数据库串行控制的开销。
8 、一个字符串类型的值能存储最大容量是多少?
512M
9 、Redis持久化机制
Redis是一个支持持久化的内存数据库,通过持久化机制把内存中的数据同步到硬盘文件来保证数据持久化。当Redis重启后通过把硬盘文件
重新加载到内存,就能达到恢复数据的目的。
实现:单独创建fork()一个子进程,将当前父进程的数据库数据复制到子进程的内存中,然后由子进程写入到临时文件中,持久化的过程结
束了,再用这个临时文件替换上次的快照文件,然后子进程退出,内存释放。
RDB是Redis默认的持久化方式。按照一定的时间周期策略把内存的数据以快照的形式保存到硬盘的二进制文件。即Snapshot快照存储,对
应产生的数据文件为dump.rdb,通过配置文件中的save参数来定义快照的周期。( 快照可以是其所表示的数据的一个副本,也可以是数据
的一个复制品。)
AOF:Redis会将每一个收到的写命令都通过Write函数追加到文件最后,类似于MySQL的binlog。当Redis重启是会通过重新执行文件中保
存的写命令来在内存中重建整个数据库的内容。当两种方式同时开启时,数据恢复Redis会优先选择AOF恢复。
10 、缓存雪崩、缓存穿透、缓存预热、缓存更新、缓存降级等问题
一、缓存雪崩
我们可以简单的理解为:由于原有缓存失效,新缓存未到期间(例如:我们设置缓存时采用了相同的过期时间,在同一时刻出现大面积的缓
存过期),所有原本应该访问缓存的请求都去查询数据库了,而对数据库CPU和内存造成巨大压力,严重的会造成数据库宕机。从而形成一
系列连锁反应,造成整个系统崩溃。
解决办法:
大多数系统设计者考虑用加锁( 最多的解决方案)或者队列的方式保证来保证不会有大量的线程对数据库一次性进行读写,从而避免失效
时大量的并发请求落到底层存储系统上。还有一个简单方案就时讲缓存失效时间分散开。
二、缓存穿透
缓存穿透是指用户查询数据,在数据库没有,自然在缓存中也不会有。这样就导致用户查询的时候,在缓存中找不到,每次都要去数据库再
查询一遍,然后返回空(相当于进行了两次无用的查询)。这样请求就绕过缓存直接查数据库,这也是经常提的缓存命中率问题。
解决办法;
最常见的则是采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被这个bitmap拦截掉,从
而避免了对底层存储系统的查询压力。另外也有一个更为简单粗暴的方法,如果一个查询返回的数据为空(不管是数据不存在,还是系统故
障),我们仍然把这个空结果进行缓存,但它的过期时间会很短,最长不超过五分钟。通过这个直接设置的默认值存放到缓存,这样第二次
到缓冲中获取就有值了,而不会继续访问数据库,这种办法最简单粗暴。
5TB的硬盘上放满了数据,请写一个算法将这些数据进行排重。如果这些数据是一些32bit大小的数据该如何解决?如果是64bit的呢?
对于空间的利用到达了一种极致,那就是Bitmap和布隆过滤器(Bloom Filter)。
Bitmap: 典型的就是哈希表
缺点是,Bitmap对于每个元素只能记录1bit信息,如果还想完成额外的功能,恐怕只能靠牺牲更多的空间、时间来完成了
布隆过滤器(推荐)
就是引入了k(k>1)k(k>1)个相互独立的哈希函数,保证在给定的空间、误判率下,完成元素判重的过程。
它的优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定的误识别率和删除困难。
Bloom-Filter算法的核心思想就是利用多个不同的Hash函数来解决“冲突”。
Hash存在一个冲突(碰撞)的问题,用同一个Hash得到的两个URL的值有可能相同。为了减少冲突,我们可以多引入几个Hash,如果通过
其中的一个Hash值我们得出某元素不在集合中,那么该元素肯定不在集合中。只有在所有的Hash函数告诉我们该元素在集合中时,才能确
定该元素存在于集合中。这便是Bloom-Filter的基本思想。
Bloom-Filter一般用于在大数据量的集合中判定某元素是否存在。
三、缓存预热
缓存预热这个应该是一个比较常见的概念,相信很多小伙伴都应该可以很容易的理解,缓存预热就是系统上线后,将相关的缓存数据直接加
载到缓存系统。这样就可以避免在用户请求的时候,先查询数据库,然后再将数据缓存的问题!用户直接查询事先被预热的缓存数据!
解决思路:
1 、直接写个缓存刷新页面,上线时手工操作下;
2 、数据量不大,可以在项目启动的时候自动进行加载;
3 、定时刷新缓存
四、缓存更新
除了缓存服务器自带的缓存失效策略之外(Redis默认的有 6 中策略可供选择),我们还可以根据具体的业务需求进行自定义的缓存淘汰,常
见的策略有两种:
( 1 )定时去清理过期的缓存;
( 2 )当有用户请求过来时,再判断这个请求所用到的缓存是否过期,过期的话就去底层系统得到新数
据并更新缓存。
两者各有优劣,第一种的缺点是维护大量缓存的key是比较麻烦的,第二种的缺点就是每次用户请求过来都要判断缓存失效,逻辑相对比较
复杂!具体用哪种方案,大家可以根据自己的应用场景来权衡
五、缓存降级
当访问量剧增、服务出现问题(如响应时间慢或不响应)或非核心服务影响到核心流程的性能时,仍然需要保证服务还是可用的,即使是有
损服务。系统可以根据一些关键数据进行自动降级,也可以配置开关实现人工降级。
降级的最终目的是保证核心服务可用,即使是有损的。而且有些服务是无法降级的(如加入购物车、结算)。
以参考日志级别设置预案:
( 1 )一般:比如有些服务偶尔因为网络抖动或者服务正在上线而超时,可以自动降级;
( 2 )警告:有些服务在一段时间内成功率有波动(如在95~100%之间),可以自动降级或人工降级,并发送告警;
( 3 )错误:比如可用率低于90%,或者数据库连接池被打爆了,或者访问量突然猛增到系统能承受的最大阀值,此时可以根据情况自动降
级或者人工降级;
( 4 )严重错误:比如因为特殊原因数据错误了,此时需要紧急人工降级。服务降级的目的,是为了防止Redis服务故障,导致数据库跟着一
起发生雪崩问题。因此,对于不重要的缓存数据,可以采取服务降级策略,例如一个比较常见的做法就是,Redis出现问题,不去数据库查
询,而是直接返回默认值给用户
11 、热点数据和冷数据是什么
热点数据,缓存才有价值
对于冷数据而言,大部分数据可能还没有再次访问到就已经被挤出内存,不仅占用内存,而且价值不大。频繁修改的数据,看情况考虑使用
缓存
对于上面两个例子,寿星列表、导航信息都存在一个特点,就是信息修改频率不高,读取通常非常高的场景。
对于热点数据,比如我们的某IM产品,生日祝福模块,当天的寿星列表,缓存以后可能读取数十万次。再举个例子,某导航产品,我们将导
航信息,缓存以后可能读取数百万次。
数据更新前至少读取两次 ,缓存才有意义。这个是最基本的策略,如果缓存还没有起作用就失效了,那就没有太大价值了。
那存不存在,修改频率很高,但是又不得不考虑缓存的场景呢?有!比如,这个读取接口对数据库的压力很大,但是又是热点数据,这个时
候就需要考虑通过缓存手段,减少数据库的压力,比如我们的某助手产品的,点赞数,收藏数,分享数等是非常典型的热点数据,但是又不
断变化,此时就需要将数据同步保存到Redis缓存,减少数据库压力
12 、单线程的redis为什么这么快
(一)纯内存操作
(二)单线程操作,避免了频繁的上下文切换
(三)采用了非阻塞I/O多路复用机制
13 、redis的数据类型,以及每种数据类型的使用场景
一共五种
(一)String
这个其实没啥好说的,最常规的set/get操作,value可以是String也可以是数字。一般做一些复杂的计数功能的缓存。
(二)hash
这里value存放的是结构化的对象,比较方便的就是操作其中的某个字段。博主在做单点登录的时候,就是用这种数据结构存储用户信息,
以cookieId作为key,设置 30 分钟为缓存过期时间,能很好的模拟出类似session的效果。
(三)list
使用List的数据结构,可以做简单的消息队列的功能。另外还有一个就是,可以利用lrange命令,做基于redis的分页功能,性能极佳,用户
体验好。本人还用一个场景,很合适—取行情信息。就也是个生产者和消费者的场景。LIST可以很好的完成排队,先进先出的原则。
(四)set
因为set堆放的是一堆不重复值的集合。所以可以做全局去重的功能。为什么不用JVM自带的Set进行去重?因为我们的系统一般都是集群部
署,使用JVM自带的Set,比较麻烦,难道为了一个做一个全局去重,再起一个公共服务,太麻烦了。
另外,就是利用交集、并集、差集等操作,可以计算共同喜好,全部的喜好,自己独有的喜好等功能。
(五)sorted set
sorted set多了一个权重参数score,集合中的元素能够按score进行排列。可以做排行榜应用,取TOP N操作
14 、redis的过期策略以及内存淘汰机制
redis采用的是定期删除+惰性删除策略。
为什么不用定时删除策略?
定时删除,用一个定时器来负责监视key,过期则自动删除。虽然内存及时释放,但是十分消耗CPU资源。在大并发请求下,CPU要将时间应用
在处理请求,而不是删除key,因此没有采用这一策略.
定期删除+惰性删除是如何工作的呢?
定期删除,redis默认每个100ms检查,是否有过期的key,有过期key则删除。需要说明的是,redis不是每个100ms将所有的key检查一次,
而是随机抽取进行检查(如果每隔100ms,全部key进行检查,redis岂不是卡死)。因此,如果只采用定期删除策略,会导致很多key到时间没
有删除。于是,惰性删除派上用场。也就是说在你获取某个key的时候,redis会检查一下,这个key如果设置了过期时间那么是否过期了?
如果过期了此时就会删除。
采用定期删除+惰性删除就没其他问题了么?
不是的,如果定期删除没删除key。然后你也没即时去请求key,也就是说惰性删除也没生效。这样,redis的内存会越来越高。那么就应该
采用内存淘汰机制。在redis.conf中有一行配置
该配置就是配内存淘汰策略的(什么,你没配过?好好反省一下自己)
volatile-lru: 从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰
volatile-ttl: 从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰
volatile-random: 从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰
allkeys-lru: 从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰
allkeys-random: 从数据集(server.db[i].dict)中任意选择数据淘汰
no-enviction(驱逐): 禁止驱逐数据,新写入操作会报错
ps: 如果没有设置 expire 的key, 不满足先决条件(prerequisites); 那么 volatile-lru, volatile-random 和volatile-ttl 策略的行为, 和
noeviction(不删除) 基本上一致
15 、Redis 常见性能问题和解决方案?
(1) Master 最好不要做任何持久化工作,如 RDB 内存快照和 AOF 日志文件
(2) 如果数据比较重要,某个 Slave 开启 AOF 备份数据,策略设置为每秒同步一次
(3) 为了主从复制的速度和连接的稳定性, Master 和 Slave 最好在同一个局域网内
(4) 尽量避免在压力很大的主库上增加从库
(5) 主从复制不要用图状结构,用单向链表结构更为稳定,即: Master <- Slave1 <- Slave2 <-Slave3...
16 、为什么Redis的操作是原子性的,怎么保证原子性的?
对于Redis而言,命令的原子性指的是:一个操作的不可以再分,操作要么执行,要么不执行。
Redis的操作之所以是原子性的,是因为Redis是单线程的。
Redis本身提供的所有API都是原子操作,Redis中的事务其实是要保证批量操作的原子性。
多个命令在并发中也是原子性的吗?
不一定, 将get和set改成单命令操作,incr 。使用Redis的事务,或者使用Redis+Lua==的方式实现。
17 、Redis事务
Redis事务功能是通过MULTI、EXEC、DISCARD和WATCH 四个原语实现的
Redis会将一个事务中的所有命令序列化,然后按顺序执行。
1.redis 不支持回滚“Redis 在事务失败时不进行回滚,而是继续执行余下的命令”, 所以 Redis 的内部可以保持简单且快速。
2.如果在一个事务中的命令出现错误,那么所有的命令都不会执行;
3.如果在一个事务中出现运行错误,那么正确的命令会被执行。
1 )MULTI命令用于开启一个事务,它总是返回OK。 MULTI执行之后,客户端可以继续向服务器发送任意多条命令,这些命令不会立即被执
行,而是被放到一个队列中,当EXEC命令被调用时,所有队列中的命令才会被执行。
2 )EXEC:执行所有事务块内的命令。返回事务块内所有命令的返回值,按命令执行的先后顺序排列。当操作被打断时,返回空值 nil 。
3 )通过调用DISCARD,客户端可以清空事务队列,并放弃执行事务, 并且客户端会从事务状态中退出。
4 )WATCH 命令可以为 Redis 事务提供 check-and-set (CAS)行为。 可以监控一个或多个键,一旦其中有一个键被修改(或删除),之
后的事务就不会执行,监控一直持续到EXEC命令
18 、Redis 的持久化机制是什么?各自的优缺点?
Redis 提供两种持久化机制 RDB 和 AOF 机制:
1 、RDBRedis DataBase)持久化方式: 是指用数据集快照的方式半持久化模式)记录 redis 数据库的所有键值对,在某个时间点将数据写入一
个临时文件,持久化结束后,用这个临时文件替换上次持久化的文件,达到数据恢复。
优点:
1 、只有一个文件 dump.rdb,方便持久化。
2 、容灾性好,一个文件可以保存到安全的磁盘。
3 、性能最大化,fork 子进程来完成写操作,让主进程继续处理命令,所以是 IO最大化。使用单独子进程来进行持久化,主进程不会进行任
何 IO 操作,保证了 redis的高性能) 4.相对于数据集大时,比 AOF 的启动效率更高。
缺点:
1 、数据安全性低。RDB 是间隔一段时间进行持久化,如果持久化之间 redis 发生故障,会发生数据丢失。所以这种方式更适合数据要求不
严谨的时候)
2 、AOFAppend-only file)持久化方式: 是指所有的命令行记录以 redis 命令请求协议的格式完全持久化存储)保存为 aof 文件。
优点:
maxmemory-policy volatile-lru
1 、数据安全,aof 持久化可以配置 appendfsync 属性,有 always,每进行一次命令操作就记录到 aof 文件中一次。
2 、通过 append 模式写文件,即使中途服务器宕机,可以通过 redis-check-aof工具解决数据一致性问题。
3 、AOF 机制的 rewrite 模式。AOF 文件没被 rewrite 之前(文件过大时会对命令进行合并重写),可以删除其中的某些命令(比如误操作
的 flushall))
缺点:
1 、AOF 文件比 RDB 文件大,且恢复速度慢。
2 、数据集大的时候,比 rdb 启动效率低。
19 、Redis 常见性能问题和解决方案:
1 、Master 最好不要写内存快照,如果 Master 写内存快照,save 命令调度 rdbSave函数,会阻塞主线程的工作,当快照比较大时对性能
影响是非常大的,会间断性暂停服务
2 、如果数据比较重要,某个 Slave 开启 AOF 备份数据,策略设置为每秒同步一 3 、为了主从复制的速度和连接的稳定性,Master 和 Slave
最好在同一个局域网
4 、尽量避免在压力很大的主库上增加从
5 、主从复制不要用图状结构,用单向链表结构更为稳定,即:Master <- Slave1<- Slave2 <- Slave3...这样的结构方便解决单点故障问题,
实现 Slave 对 Master的替换。如果 Master 挂了,可以立刻启用 Slave1 做 Master,其他不变。
20 、redis 过期键的删除策略?
1 、定时删除:在设置键的过期时间的同时,创建一个定时器 timer). 让定时器在键的过期时间来临时,立即执行对键的删除操作。
2 、惰性删除:放任键过期不管,但是每次从键空间中获取键时,都检查取得的键是否过期,如果过期的话,就删除该键;如果没有过期,就返
回该键。
3 、定期删除:每隔一段时间程序就对数据库进行一次检查,删除里面的过期键。至于要删除多少过期键,以及要检查多少个数据库,则由算
法决定。
21 、Redis 的回收策略(淘汰策略)?
volatile-lru: 从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰
volatile-ttl: 从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰
volatile-random: 从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰
allkeys-lru: 从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰
allkeys-random: 从数据集(server.db[i].dict)中任意选择数据淘汰
no-enviction(驱逐): 禁止驱逐数据
注意这里的 6 种机制,volatile 和 allkeys 规定了是对已设置过期时间的数据集淘汰数据还是从全部数据集淘汰数据,后面的 lru、ttl
以及 random 是三种不同的淘汰策略,再加上一种 no-enviction 永不回收的策略
使用策略规则:
1 、如果数据呈现幂律分布,也就是一部分数据访问频率高,一部分数据访问频率低,则使用 allkeys-lru
2 、如果数据呈现平等分布,也就是所有的数据访问频率都相同,则使用allkey
22 、为什么 edis 需要把所有数据放到内存中?
Redis 为了达到最快的读写速度将数据都读到内存中,并通过异步的方式将数据写入磁盘。所以 redis 具有快速和数据持久化的特征。如果
不将数据放在内存中,磁盘 I/O 速度为严重影响 redis 的性能。在内存越来越便宜的今,redis 将会越来越受欢迎。如果设置了最大使用的
内存,则数据已有记录数达到内存限值后不能继续插入新值。
23 、Redis 的同步机制了解么?
Redis 可以使用主从同步,从从同步。第一次同步时,主节点做一次 bgsave,并同时将后续修改操作记录到内存 buffer,待完成后将 rdb
文件全量同步到复制节点,复制节点接受完成后将 rdb 镜像加载到内存。加载完成后,再通知主节点将期间修改的操作记录同步到复制节点
进行重放就完成了同步过程。
24 、Pipeline 有什么好处,为什么要用 pipeline?
可以将多次 IO 往返的时间缩减为一次,前提是 pipeline 执行的指令之间没有因果相关性。使用 redis-benchmark 进行压测的时候可以发
现影响 redis 的 QPS峰值的一个重要因素是 pipeline 批次指令的数目。
25 、是否使用过 Redis 集群,集群的原理是什么?
1)、Redis Sentinal 着眼于高可用,在 master 宕机时会自动将 slave 提升为master,继续提供服务。
2)、Redis Cluster 着眼于扩展性,在单个 redis 内存不足时,使用 Cluster 进行分片存储。
26 、Redis 集群方案什么情况下会导致整个集群不可用?
答:有 A,B,C 三个节点的集群,在没有复制模型的情况下,如果节点 B 失败了,那么整个集群就会以为缺少 5501-11000 这个范围的槽而不
可用。
27 、Redis 支持的 Java 客户端都有哪些?官方推荐用哪个?
Redisson、Jedis、lettuce 等等,官方推荐使用 Redisson。
28 、Jedis 与 Redisson 对比有什么优缺点?
Jedis 是 Redis 的 Java 实现的客户端,其 API 提供了比较全面的 Redis 命令的支持;Redisson 实现了分布式和可扩展的 Java 数据结构,和
Jedis 相比,功能较为简单,不支持字符串操作,不支持排序、事务、管道、分区等 Redis 特性。Redisson 的宗旨是促进使用者对 Redis 的
关注分离,从而让使用者能够将精力更集中地放在处理业务逻辑上
29 、Redis 如何设置密码及验证密码?
设置密码:config set requirepass 123456
授权密码:auth 123456
30 、说说 Redis 哈希槽的概念?
Redis 集群没有使用一致性 hash,而是引入了哈希槽的概念,Redis 集群有 16384 个哈希槽,每个 key 通过 CRC16 校验后对 16384 取模来
决定放置哪个槽,集群的每个节点负责一部分 hash 槽。
31 、Redis 集群的主从复制模型是怎样的?
为了使在部分节点失败或者大部分节点无法通信的情况下集群仍然可用,所以集群使用了主从复制模型,每个节点都会有 N-1 个复制品.
32 、Redis 集群会有写操作丢失吗?为什么?
Redis 并不能保证数据的强一致性,这意味这在实际中集群在特定的条件下可能会丢失写操作。
33 、Redis 集群之间是如何复制的?
异步复制
34 、Redis 集群最大节点个数是多少?
16384 个
35 、Redis 集群如何选择数据库?
Redis 集群目前无法做数据库选择,默认在 0 数据库。
36 、怎么测试 Redis 的连通性?
使用 ping 命令
37 、怎么理解 Redis 事务?
1 )事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请
求所打断。
2 )事务是一个原子操作:事务中的命令要么全部被执行,要么全部都不执行。
38 、Redis 事务相关的命令有哪几个?
MULTI、EXEC、DISCARD、WATCH
39 、Redis key 的过期时间和永久有效分别怎么设置?
EXPIRE 和 PERSIST 命令。
40 、Redis 如何做内存优化?
尽可能使用散列表(hashes),散列表(是说散列表里面存储的数少)使用的内存非常小,所以你应该尽可能的将你的数据模型抽象到一
个散列表里面。比如你的 web 系统中有一个用户对象,不要为这个用户的名称,姓氏,邮箱,密码设置单独的 key,而是应该把这个用户的
所有信息存储到一张散列表里面.
41 、Redis 回收进程如何工作的?
一个客户端运行了新的命令,添加了新的数据。Redi 检查内存使用情况,如果大于 maxmemory 的限制, 则根据设定好的策略进行回收。
一个新的命令被执行,等等。所以我们不断地穿越内存限制的边界,通过不断达到边界然后不断地回收回到边界以下。如果一个命令的结果
导致大量内存被使用(例如很大的集合的交集保存到一个新的键),不用多久内存限制就会被这个内存使用量超越。
42 、都有哪些办法可以降低 Redis 的内存使用情况呢?
如果你使用的是 32 位的 Redis 实例,可以好好利用 Hash,list,sorted set,set等集合类型数据,因为通常情况下很多小的 Key-Value 可以用
更紧凑的方式存放到一起。
43 、Redis 的内存用完了会发生什么?
如果达到设置的上限,Redis 的写命令会返回错误信息(但是读命令还可以正常返回。)或者你可以将 Redis 当缓存来使用配置淘汰机制,
当 Redis 达到内存上限时会冲刷掉旧的内容。
44 、一个 Redis 实例最多能存放多少的 keys?List、Set、Sorted Set 他们最多能存放多少
元素
理论上 Redis 可以处理多达 232 的 keys,并且在实际中进行了测试,每个实例至少存放了 2 亿 5 千万的 keys。我们正在测试一些较大的
值。任何 list、set、和 sorted set 都可以放 232 个元素。换句话说,Redis 的存储极限是系统中的可用内存值。
45 、MySQL 里有 2000w 数据,redis 中只存 20w 的数据,如何保证 redis 中的数据都是热
点数据?
Redis 内存数据集大小上升到一定大小的时候,就会施行数据淘汰策略。相关知识:Redis 提供 6 种数据淘汰策略:
volatile-lru: 从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰
volatile-ttl: 从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰
volatile-random: 从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰
allkeys-lru: 从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰
allkeys-random: 从数据集(server.db[i].dict)中任意选择数据淘汰
no-enviction(驱逐): 禁止驱逐数据
46 、Redis 最适合的场景?
1 、会话缓存(Session Cache)
最常用的一种使用 Redis 的情景是会话缓存(session cache)。用 Redis 缓存会话比其他存储(如 Memcached)的优势在于:Redis 提供
持久化。当维护一个不是严格要求一致性的缓存时,如果用户的购物车信息全部丢失,大部分人都会不高兴的,现在,他们还会这样吗?
幸运的是,随着 Redis 这些年的改进,很容
易找到怎么恰当的使用 Redis 来缓存会话的文档。甚至广为人知的商业平台Magento 也提供 Redis 的插件。
2 、全页缓存(FPC)
除基本的会话 token 之外,Redis 还提供很简便的 FPC 平台。回到一致性问题,即使重启了 Redis 实例,因为有磁盘的持久化,用户也不
会看到页面加载速度的下降,这是一个极大改进,类似 PHP 本地 FPC。 再次以 agento 为例,Magento提供一个插件来使用 Redis 作为全
页缓存后端。 此外,对 WordPress 的用户来说,Pantheon 有一个非常好的插件 wp-redis,这个插件能帮助你以最快速度加载你曾浏览过
的页面。
3 、队列
Reids 在内存存储引擎领域的一大优点是提供 list 和 set 操作,这使得 Redis能作为一个很好的消息队列平台来使用。Redis 作为队列使用的
操作,就类似于本地程序语言(如 Python)对 list 的 push/pop 操作。 如果你快速的在 Google中搜索“Redis queues”,你马上就能找到大
量的开源项目,这些项目的目的就是利用 Redis 创建非常好的后端工具,以满足各种队列需求。例如,Celery 有一个后台就是使用 Redis
作为 broker,你可以从这里去查看。
4 ,排行榜/计数器
Redis 在内存中对数字进行递增或递减的操作实现的非常好。集合(Set)和有序集合(Sorted Set)也使得我们在执行这些操作的时候变的
非常简单,Redis 只是正好提供了这两种数据结构。所以,我们要从排序集合中获取到排名最靠前的 10 个用户–我们称之为“user_scores”,
我们只需要像下面一样执行即可: 当然,这是假定你是根据你用户的分数做递增的排序。如果你想返回用户及用户的分数,你需要这样执
行: ZRANGE user_scores 0 10 WITHSCORES Agora Games 就是一个很好的例子,用 Ruby 实现的,它的排行榜就是使用 Redis 来存储数
据的,
你可以在这里看到。
5 、发布/订阅
最后(但肯定不是最不重要的)是 Redis 的发布/订阅功能。发布/订阅的使用场景确实非常多。我已看见人们在社交网络连接中使用,还可
作为基于发布/订阅的脚本触发器,甚至用 Redis 的发布/订阅功能来建立聊天系统!
47 、假如 Redis 里面有 1 亿个 key,其中有 10w 个 key 是以某个固定的已知的前缀开头
的,如果将它们全部找出来?
使用 keys 指令可以扫出指定模式的 key 列表。 对方接着追问:如果这个 redis 正在给线上的业务提供服务,那使用 keys 指令会 有什么问
题?
这个时候你要回答 redis 关键的一个特性:redis 的单线程的。keys 指令会导致线程阻塞一段时间,线上服务会停顿,直到指令执行完毕,
服务才能恢复。这个时候可以使用 scan 指令,scan 指令可以无阻塞的提取出指定模式的 key 列表,但是会有一定的重复概率,在客户端做
一次去重就可以了,但是整体所花费的时间会比直接用 keys 指令长。
48 、如果有大量的 key 需要设置同一时间过期,一般需要注意什么?
如果大量的 key 过期时间设置的过于集中,到过期的那个时间点,redis 可能会出现短暂的卡顿现象。一般需要在时间上加一个随机值,使
得过期时间分散一些。
49 、使用过 Redis 做异步队列么,你是怎么用的?
一般使用 list 结构作为队列,rpush 生产消息,lpop 消费消息。当 lpop 没有消息的时候,要适当 sleep 一会再重试。
如果对方追问可不可以不用 sleep 呢?
list 还有个指令叫 blpop,在没有消息的时候,它会阻塞住直到消息到来。如果对方追问能不能生产一次消费多次呢?使用 pub/sub 主题订
阅者模式,可以实现1:N 的消息队列。
如果对方追问 pub/sub 有什么缺点?
在消费者下线的情况下,生产的消息会丢失,得使用专业的消息队列如 RabbitMQ等。
如果对方追问 redis 如何实现延时队列?
我估计现在你很想把面试官一棒打死如果你手上有一根棒球棍的话,怎么问的这么详细。但是你很克制,然后神态自若的回答道:使用
sortedset,拿时间戳作为score,消息内容作为 key 调用 zadd 来生产消息,消费者用 zrangebyscore 指令获取 N 秒之前的数据轮询进行
处理。到这里,面试官暗地里已经对你竖起了大拇指。但是他不知道的是此刻你却竖起了中指,在椅子背后。
50 、使用过 Redis 分布式锁么,它是什么回事
先拿 setnx 来争抢锁,抢到之后,再用 expire 给锁加一个过期时间防止锁忘记了释放。
这时候对方会告诉你说你回答得不错,然后接着问如果在 setnx 之后执行 expire之前进程意外 crash 或者要重启维护了,那会怎么样?
这时候你要给予惊讶的反馈:唉,是喔,这个锁就永远得不到释放了。紧接着你需要抓一抓自己得脑袋,故作思考片刻,好像接下来的结果
是你主动思考出来的,然后回答:我记得 set 指令有非常复杂的参数,这个应该是可以同时把 setnx 和expire 合成一条指令来用的!对方这
时会显露笑容,心里开始默念:摁,这小子还不错。
Memcached面试题
1 、Memcached 是什么,有什么作用?
Memcached 是一个开源的,高性能的内存绶存软件,从名称上看 Mem 就是内存的意思,而 Cache 就是缓存的意思。Memcached 的作
用:通过在事先规划好的内存空间中临时绶存数据库中的各类数据,以达到减少业务对数据库的直接高并发访问,从而达到提升数据库的访
问性能,加速网站集群动态应用服务的能力。
2 、memcached 服务在企业集群架构中有哪些应用场景?
一、作为数据库的前端缓存应用
a、完整缓存(易),静态缓存
例如:商品分类(京东),以及商品信息,可事先放在内存里,然后再对外提供数据访问,这种先放到内存,我们称之为预热,(先把数据
存缓存中),用户访问时可以只读取 memcached 缓存,不读取数据库了。
b、执点缓存(难)
需要前端 web 程序配合,只缓存热点的数据,即缓存经常被访问的数据。先预热数据库里的基础数据,然后在动态更新,选读取缓存,如
果缓存里没有对应的数据,程序再去读取数据库,然后程序把读取的新数据放入缓存存储。
特殊说明 :
如果碰到电商秒杀等高并发的业务,一定要事先预热,或者其它思想实现,例如:称杀只是获取资格,而不是瞬间秒杀到手商品。
那么什么是获取资格?
就是在数据库中,把 0 标成 1.就有资格啦。再慢慢的去领取商品订单。因为秒杀过程太长会占用服务器资源。
如果数据更新,同时触发缓存更新,防止给用户过期数据。
对于持久化缓存存储系统,例如:redis,可以替代一部分数据库的存储,一些简单的数据业务,投票,统计,好友关注,商品分类等。
nosql= not onlysql
二、作业集群的 session 会话共享存储。
Memcached 服务在不同企业业务应用场景中的工作流程
当 web 程序需要访问后端数据库获取数据时会优先访问 Memcached 内存缓存,如果缓存中有数据就直接获取返回前端服务及用户,如
果没有数据(没有命中),在由程序请求后端的数据库服务器,获取到对应的数据后,除了返回给前端服务及用户数据外,还会把数据放到
Memcached 内存中进行缓存,等待下次请求被访问,Memcache 内存始终是数据库的挡箭牌,从而大大的减轻数据库的访问压力,提高
整个网站架构的响应速度,提升了用户体验。
当程序更新,修改或删除数据库中已有的数据时,会同时发送请求通知Memcached 已经缓存的同一个 ID 内容的旧数据失效,从而保证
Memcache中数据和数据库中的数据一致。
如果在高并发场合,除了通知 Memcached 过程的缓存失效外,还会通过相关机制,使得在用户访问新数据前,通过程序预先把更新过的
数据推送到memcache 中缓存起来,这样可以减少数据库的访问压力,提升 Memcached中缓存命中率。
数据库插件可以再写入更新数据库后,自动抛给 MC 缓存起来,自身不Cache.
2 、Memcached 服务分布式集群如何实现?
特殊说明:Memcached 集群和 web 服务集群是不一样的,所有 Memcached 的数据总和才是数据库的数据。每台 Memcached 都是部分
数据。(一台 memcached 的数据,就是一部分 mysql 数据库的数据)
a、程序端实现
程序加载所有 mc 的 ip 列表,通过对 key 做 hash (一致性哈希算法)
例如:web1 (key)===>对应 A,B,C,D,E,F,G.....若干台服务器。(通过哈希算法实现)
b、负载均衡器
通过对 key 做 hash (一致性哈希算法)一致哈希算法的目的是不但保证每个对象只请求一个对应的服务器,而且当节点宕机,缓存服务器的
更新重新分配比例降到最低。
3 、Memcached 服务特点及工作原理是什么?
a、完全基于内存缓存的
b、节点之间相互独立
c、C/S 模式架构,C 语言编写,总共 2000 行代码。
d、异步I/O 模型,使用 libevent 作为事件通知机制。
e、被缓存的数据以 key/value 键值对形式存在的。
f、全部数据存放于内存中,无持久性存储的设计,重启服务器,内存里的数据会丢失。
g、当内存中缓存的数据容量达到启动时设定的内存值时,就自动使用 LRU 算法删除过期的缓存数据。
h、可以对存储的数据设置过期时间,这样过期后的数据自动被清除,服务本身不会监控过期,而是在访问的时候查看 key 的时间戳,判断是
否过期。
j、memcache 会对设定的内存进行分块,再把块分组,然后再提供服务
4 、简述 Memcached 内存管理机制原理?
早期的 Memcached 内存管理方式是通过 malloc 的分配的内存,使用完后通过free 来回收内存,这种方式容易产生内存碎片,并降低操作
系统对内存的管理效率。加重操作系统内存管理器的负担,最坏的情况下,会导致操作系统比memcached 进程本身还慢,为了解决这个问
题,Slab Allocation 内存分配机制就延生了。
现在 Memcached 利用 Slab Allocation 机制来分配和管理内存。
Slab Allocation 机制原理是按照预先规定的大小,将分配给 memcached 的内存分割成特定长度的内存块(chunk),再把尺寸相同的内存
块,分成组(chunks slab class),这些内存块不会释放,可以重复利用。
而且,slab allocator 还有重复使用已分配的内存的目的。 也就是说,分配到的内存不会释放,而是重复利用。
Slab Allocation 的主要术语Page分配给 Slab 的内存空间,默认是 1MB。分配给 Slab 之后根据 slab 的大小切分成chunk。
Chunk
用于缓存记录的内存空间。
SlabClass
特定大小的 chunk 的组
5 、memcached 是怎么工作的?
Memcached 的神奇来自两阶段哈希(two-stage hash)。Memcached 就像一个巨大的、存储了很多<key,value>对的哈希表。通过 key,
可以存储或查询任意的数据。
客户端可以把数据存储在多台 memcached 上。当查询数据时,客户端首先参考节点列表计算出 key 的哈希值(阶段一哈希),进而选中
一个节点;客户端将请求发送给选中的节点,然后 memcached 节点通过一个内部的哈希算法(阶段二哈希),查找真正的数据(item)
6 、memcached 最大的优势是什么?
Memcached 最大的好处就是它带来了极佳的水平可扩展性,特别是在一个巨大的系统中。由于客户端自己做了一次哈希,那么我们很容易
增加大量 memcached到集群中。memcached 之间没有相互通信,因此不会增加 memcached 的负载;没有多播协议,不会网络通信量爆
炸(implode)。memcached 的集群很好用。内存不够了?增加几台 memcached 吧;CPU 不够用了?再增加几台吧;有多余的内存?
在增加几台吧,不要浪费了。
基于 memcached 的基本原则,可以相当轻松地构建出不同类型的缓存架构。除了这篇 FAQ,在其他地方很容易找到详细资料的。
7 、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 会遇到扩展问题(scalabilityissues)。在多核 CPU 上,query cache 会增加一个全局锁
(global lock), 由于需要刷新更多的缓存数据,速度会变得更慢。
在 MySQL 的 query cache 中,我们是不能存储任意的数据的(只能是SQL 查询结果)。而利用 emcached,我们可以搭建出各种高效的
缓存。比如,可以执行多个独立的查询,构建出一个用户对象(user object),然后将用户对象缓存到 memcached 中。而 query cache
是 SQL 语句级别的,不可能做到这一点。在小的网站中,query cache 会有所帮助,但随着网站规模的增加,query cache 的弊将大于利。
query cache能够利用的内存容量受到MySQL服务器空闲内存空间的限制。给数据库服务器增加更多的内存来缓存数据,固然是很好的。
但是,有了memcached,只要您有空闲的内存,都可以用来增加 memcached 集群的规
模,然后您就可以缓存更多的数据。
8 、memcached 和服务器的 local cache(比如 PHP 的 APC、mmap 文件等)相比,有
什么优缺点?
首先,local cache 有许多与上面(query cache)相同的问题。local cache 能够利用的内存容量受到(单台)服务器空闲内存空间的限制。不
过,local cache 有一 点比 memcached 和 query cache 都要 好, 那就 是它 不但 可以 存储 任意的 数据 ,而 且没 有网 络存 取的 延迟 。
local cache 的数据查询更快。考虑把 highly common 的数据放在 localcache 中吧。如果每个页面都需要加载一些数量较少的数据,考
虑把它们放在local cached 吧。
local cache 缺少集体失效(groupinvalidation)的特性。在 memcached 集群中,删除或更新一个 key 会让所有的观察者觉察到。但是
在 local cache 中, 我们只能通知所有的服务器刷新 cache(很慢,不具扩展性),或者仅仅依赖缓存超时失效机制。
local cache 面临着严重的内存限制,这一点上面已经提到。
9 、memcached 的 cache 机制是怎样的?
Memcached 主要 的 cache 机制 是 LRU(最 近最 少用 )算 法 +超时 失效 。当 您存数据 到 memcached 中, 可以 指定 该数 据在 缓存
中可 以呆 多久 Which is forever,or some time in the future。如 果 memcached 的内 存不 够用 了, 过期 的 slabs会优 先被 替换 ,接 着
就 轮到 最老 的未 被使 用的 slabs。
10 、memcached 如何实现冗余机制?
不实 现!我们 对这 个问 题感 到很 惊讶 。Memcached 应该 是应 用的 缓存 层 。它的 设计本 身就 不带 有任 何冗 余机 制。 如果 一个
memcached 节点 失去 了所 有数 据, 您应该 可以 从数 据源 (比 如数 据库 )再 次获 取到 数据 。您 应该 特别 注意 ,您 的应 用应该 可
以 容忍 节点 的失 效。 不要 写一 些糟 糕的 查询 代码 ,寄 希望 于 memcached 来保证一切!如果您担心节点失效会大大加重数据库的负
担,那么您可以采取一些办法。比如您可以增加更多的节点(来减少丢失一个节点的影响),热备节点(在其他节点 down 了的时候接管
IP),等等
11 、memcached 如何处理容错的?
不处理! 在 memcached 节点失效的情况下,集群没有必要做任何容错处理。如果发生了节点失效,应对的措施完全取决于用户。节点失
效时,下面列出几种方案供您选择:
忽略它! 在失效节点被恢复或替换之前,还有很多其他节点可以应对节点失效带来的影响。
把失效的节点从节点列表中移除。做这个操作千万要小心!在默认情况下(余数式哈希算法),客户端添加或移除节点,会导致所有的缓
存数据不可用!因为哈希参照的节点列表变化了,大部分 key 会因为哈希值的改变而被映射到(与原来)不同的节点上。
启动热备节点,接管失效节点所占用的 IP。这样可以防止哈希紊乱(hashing chaos)。
如果希望添加和移除节点,而不影响原先的哈希结果,可以使用一致性哈希算法(consistent hashing)。您可以百度一下一致性哈希算
法。支持一致性哈希的客户端已经很成熟,而且被广泛使用。去尝试一下吧!
两次哈希(reshing)。当客户端存取数据时,如果发现一个节点 down了,就再做一次哈希(哈希算法与前一次不同),重新选择另一
个节点(需要注意的时,客户端并没有把 down 的节点从节点列表中移除,下次还是有可能先哈希到它)。如果某个节点时好时坏,两次哈
希的方法就有风险了,好的节点和坏的节点上都可能存在脏数据(stale data)。
12 、如何将 memcached 中 item 批量导入导出?
您不应该这样做!Memcached 是一个非阻塞的服务器。任何可能导致memcached 暂停或瞬时拒绝服务的操作都应该值得深思熟虑。向
memcached中批量导入数据往往不是您真正想要的!想象看,如果缓存数据在导出导入之间发生了变化,您就需要处理脏数据了;
13 、如果缓存数据在导出导入之间过期了,您又怎么处理这些数据呢?
因此,批量导出导入数据并不像您想象中的那么有用。不过在一个场景倒是很有用。如果您有大量的从不变化的数据,并且希望缓存很快热
(warm)起来,批量导入缓存数据是很有帮助的。虽然这个场景并不典型,但却经常发生,因此我们会考虑在将来实现批量导出导入的功
能。如果一个 memcached 节点 down 了让您很痛苦,那么您还会陷入其他很多麻烦。您的系统太脆弱了。您需要做一些优化工作。比如
处理”惊群”问题(比如memcached 节点都失效了,反复的查询让您的数据库不堪重负...这个问题在 FAQ的其他提到过),或者优化不好的
查询。记住,Memcached 并不是您逃避优化查询的借口。
14 、memcached 是如何做身份验证的?
没有身份认证机制!memcached 是运行在应用下层的软件(身份验证应该是应用上层的职责)。memcached 的客户端和服务器端之所以
是轻量级的,部分原因就是完全没有实现身份验证机制。这样,memcached 可以很快地创建新连接,服务器端也无需任何配置。如果您希
望限制访问,您可以使用防火墙,或者让 memcached 监听 unix domain socket
15 、memcached 的多线程是什么?如何使用它们?
线程就是定律(threads rule)!在 Steven Grimm 和 Facebook 的努力下,memcached 1.2 及更高版本拥有了多线程模式。多线程模式
允许 memcached 能够充分利用多个 CPU,并在 CPU 之间共享所有的缓存数据。memcached 使用一种简单的锁机制来保证数据更新操作
的互斥。相比在同一个物理机器上运行多个
memcached 实例,这种方式能够更有效地处理 multi gets。
如果您的系统负载并不重,也许您不需要启用多线程工作模式。如果您在运行一个拥有大规模硬件的、庞大的网站,您将会看到多线程的好
处。
简单地总结一下:命令解析(memcached 在这里花了大部分时间)可以运行在多线程模式下。memcached 内部对数据的操作是基于很多
全局锁的(因此这部分工作不是多线程的)。未来对多线程模式的改进,将移除大量的全局锁,提高memcached 在负载极高的场景下的性
能。
16 、memcached 能接受的 key 的最大长度是多少?
key 的最大长度是 250 个字符。需要注意的是, 250 是 memcached 服务器端内部的限制,如果您使用的客户端支持”key 的前缀”或类似特
性,那么 key(前缀+原始 key)的最大长度是可以超过 250 个字符的。我们推荐使用使用较短的 key,因为可以节省内存和带宽。
17 、memcached 对 item 的过期时间有什么限制?
过期时间最大可以达到 30 天。memcached 把传入的过期时间(时间段)解释成时间点后,一旦到了这个时间点,memcached 就把
item 置为失效状态。这是一个简单但 obscure 的机制。
18 、memcached 最大能存储多大的单个 item?
1MB。如果你的数据大于 1MB,可以考虑在客户端压缩或拆分到多个 key 中。
为什么单个 item 的大小被限制在 1M byte 之内?
啊...这是一个大家经常问的问题!
简单的回答:因为内存分配器的算法就是这样的。
详细的回答:Memcached 的内存存储引擎(引擎将来可插拔...),使用 slabs 来管理内存。内存被分成大小不等的 slabs chunks(先分成
大小相等的 slabs,然后每个 slab 被分成大小相等 chunks,不同 slab 的 chunk 大小是不相等的)。chunk的大小依次从一个最小数开
始,按某个因子增长,直到达到最大的可能值。
19 、memcached 能够更有效地使用内存吗?
Memcache 客户端仅根据哈希算法来决定将某个 key 存储在哪个节点上,而不考虑节点的内存大小。因此,您可以在不同的节点上使用大
小不等的缓存。但是一般都是这样做的:拥有较多内存的节点上可以运行多个 memcached 实例,每个实例使用的内存跟其他节点上的实
例相同。
20 、什么是二进制协议,我该关注吗?
关于二进制最好的信息当然是二进制协议规范:
二进制协议尝试为端提供一个更有效的、可靠的协议,减少客户端/服务器端因处理协议而产生的 CPU 时间。
根据 Facebook 的测试,解析 ASCII 协议是 memcached 中消耗 CPU 时间最多的环节。所以,我们为什么不改进 ASCII 协议呢?
21 、memcached 的内存分配器是如何工作的?为什么不适用malloc/free!?为何要使用
slabs?
实际上,这是一个编译时选项。默认会使用内部的 slab 分配器。您确实确实应该使用内建的 slab 分配器。最早的时候,memcached 只使
用 malloc/free 来管理内存。然而,这种方式不能与 OS 的内存管理以前很好地工作。反复地 malloc/free造成了内存碎片,OS 最终花费大
量的时间去查找连续的内存块来满足 malloc 的请求,而不是运行 memcached 进程。如果您不同意,当然可以使用 malloc!
只是不要在邮件列表中抱怨啊
slab 分配器就是为了解决这个问题而生的。内存被分配并划分成 chunks,一直被重复使用。因为内存被划分成大小不等的 slabs,如果
item 的大小与被选择存放它的 slab 不是很合适的话,就会浪费一些内存。Steven Grimm 正在这方面已经做出了有效的改进。
22 、memcached 是原子的吗?
所有的被发送到 memcached 的单个命令是完全原子的。如果您针对同一份数据同时发送了一个 set 命令和一个 get 命令,它们不会影响对
方。它们将被串行化、先后执行。即使在多线程模式,所有的命令都是原子的,除非程序有 bug:)
命令序列不是原子的。如果您通过 get 命令获取了一个 item,修改了它,然后想把它 set 回 memcached,我们不保证这个 item 没有被其
他进程(process,未必是操作系统中的进程)操作过。在并发的情况下,您也可能覆写了一个被其他进程 set 的 item。
memcached 1.2.5 以及更高版本,提供了 gets 和 cas 命令,它们可以解决上面的问题。如果您使用 gets 命令查询某个 key 的 item,
memcached 会给您返回该 item 当前值的唯一标识。如果您覆写了这个 item 并想把它写回到 memcached中,您可以通过 cas 命令把那个
唯一标识一起发送给 memcached。如果该 item存放在 memcached 中的唯一标识与您提供的一致,您的写操作将会成功。如果另一个进
程在这期间也修改了这个 item,那么该 item 存放在 memcached 中的唯一标识将会改变,您的写操作就会失败
23 、如何实现集群中的 session 共享存储?
Session 是运行在一台服务器上的,所有的访问都会到达我们的唯一服务器上,这样我们可以根据客户端传来的 sessionID,来获取
session,或在对应 Session 不存在的情况下(session 生命周期到了/用户第一次登录),创建一个新的 Session;但是,如果我们在集群
环境下,假设我们有两台服务器 A,B,用户的请求会由
Nginx 服务器进行转发(别的方案也是同理),用户登录时,Nginx 将请求转发至服务器 A 上,A 创建了新的 session,并将 SessionID 返
回给客户端,用户在浏览其他页面时,客户端验证登录状态,Nginx 将请求转发至服务器 B,由于 B 上并没有对应客户端发来 sessionId 的
session,所以会重新创建一个新的 session,并且再将这个新的 sessionID 返回给客户端,这样,我们可以想象一下,用户每一次操作都有
1/2 的概率进行再次的登录,这样不仅对用户体验特别差,还会让服务器上的 session 激增,加大服务器的运行压力。
为了解决集群环境下的 seesion 共享问题,共有 4 种解决方案:
1.粘性 session
粘性 session 是指 Ngnix 每次都将同一用户的所有请求转发至同一台服务器上,即将用户与服务器绑定。
2.服务器 session 复制
即每次 session 发生变化时,创建或者修改,就广播给所有集群中的服务器,使所有的服务器上的 session 相同。
3.session 共享
缓存 session,使用 redis, memcached。
4.session 持久化
将 session 存储至数据库中,像操作数据一样才做 session
24 、memcached 与 redis 的区别
1 、Redis 不仅仅支持简单的 k/v 类型的数据,同时还提供 list,set,zset,hash等数据结构的存储。而 memcache 只支持简单数据类型,
需要客户端自己处理复杂对象
2 、Redis 支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用(PS:持久化在 rdb、aof)。
3 、由于 Memcache 没有持久化机制,因此宕机所有缓存数据失效。Redis 配置为持久化,宕机重启后,将自动加载宕机时刻的数据到缓存
系统中。具有更好的灾备机制。
4 、Memcache 可以使用 Magent 在客户端进行一致性 hash 做分布式。Redis 支持在服务器端做分布式(PS:Twemproxy/Codis/Redis-
cluster 多种分布式实现方式)
5 、Memcached 的简单限制就是键(key)和 Value 的限制。最大键长为 250 个字符。可以接受的储存数据不能超过 1MB(可修改配置文
件变大),因为这是典型 slab 的最大值,不适合虚拟机使用。而 Redis 的 Key 长度支持到 512k。
6 、Redis 使用的是单线程模型,保证了数据按顺序提交。Memcache 需要使用cas 保证数据一致性。CAS(Check and Set)是一个确保并
发一致性的机制,属于“乐观锁”范畴;原理很简单:拿版本号,操作,对比版本号,如果一致就操作,不一致就放弃任何操作cpu 利用。由
于 Redis 只使用单核,而 Memcached 可以使用多核,所以平均每一个核上 Redis 在存储小数据时比 Memcached 性能更 高。而在 100k
以上的数据中,Memcached 性能要高于 Redis 。
7 、memcache 内存管理:使用 Slab Allocation。原理相当简单,预先分配一系列大小固定的组,然后根据数据大小选择最合适的块存储。
避免了内存碎片。(缺点:不能变长,浪费了一定空间)memcached 默认情况下下一个 slab 的最大值为前一个的 1.25 倍。
8 、redis 内存管理: Redis 通过定义一个数组来记录所有的内存分配情况, Redis采用的是包装的 malloc/free,相较于 Memcached 的内
存 管理方法来说,要简单很多。由于 malloc 首先以链表的方式搜索已管理的内存中可用的空间分配,导致内存碎片比较多
MongoDB面试题
1 、mongodb是什么?
MongoDB 是由 C++语言编写的,是一个基于分布式文件存储的开源数据库系统。 在高负载的情况下,添加更多的节点,可以保证服务器性
能。 MongoDB 旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。
MongoDB 将数据存储为一个文档,数据结构由键值(key=>value)对组成。 MongoDB 文档类似于 JSON 对象。字段值可以包含其他文档,
数组及文档数组。
2 、mongodb有哪些特点?
1.MongoDB 是一个面向文档存储的数据库,操作起来比较简单和容易。
2.你可以在 MongoDB 记录中设置任何属性的索引 (如: FirstName="Sameer",Address="8 Gandhi Road")来实现更快的排序。
3.你可以通过本地或者网络创建数据镜像,这使得 MongoDB 有更强的扩展性。
4.如果负载的增加(需要更多的存储空间和更强的处理能力) ,它可以分布在计算机网络中的其他节点上这就是所谓的分片。
5.Mongo 支持丰富的查询表达式。查询指令使用 JSON 形式的标记,可轻易查询文档中内嵌的对象及数组。
6.MongoDb 使用 update()命令可以实现替换完成的文档(数据)或者一些指定的数据字段 。
7.Mongodb 中的 Map/reduce 主要是用来对数据进行批量处理和聚合操作。
8.Map 和 Reduce。 Map 函数调用 emit(key,value)遍历集合中所有的记录,将 key 与 value 传给 Reduce 函数进行处理。
9.Map 函数和 Reduce 函数是使用 Javascript 编写的,并可以通过 db.runCommand 或 mapreduce 命令来执行 MapReduce 操作。
- GridFS 是 MongoDB 中的一个内置功能,可以用于存放大量小文件。
- MongoDB 允许在服务端执行脚本, 可以用 Javascript 编写某个函数,直接在服务端执行,也
可以把函数的定义存储在服务端,下次直接调用即可。
3 、你说的NoSQL数据库是什么意思?NoSQL与RDBMS直接有什么区别?为什么要使用和不使
用NoSQL数据库?说一说NoSQL数据库的几个优点?
NoSQL是非关系型数据库,NoSQL = Not Only SQL。
关系型数据库采用的结构化的数据,NoSQL采用的是键值对的方式存储数据。
在处理非结构化/半结构化的大数据时;在水平方向上进行扩展时;随时应对动态增加的数据项时可以优先考虑使用NoSQL数据库。
在考虑数据库的成熟度;支持;分析和商业智能;管理及专业性等问题时,应优先考虑关系型数据库。
4 、NoSQL数据库有哪些类型?
NoSQL数据库的类型
例如:MongoDB, Cassandra, CouchDB, Hypertable, Redis, Riak, Neo4j, HBASE, Couchbase, MemcacheDB, RevenDB and Voldemort
are the examples of NoSQL databases.详细阅读。
5 、MySQL与MongoDB之间最基本的差别是什么?
MySQL和MongoDB两者都是免费开源的数据库。MySQL和MongoDB有许多基本差别包括数据的表示(data representation),查询,关
系,事务,schema的设计和定义,标准化(normalization),速度和性能。
通过比较MySQL和MongoDB,实际上我们是在比较关系型和非关系型数据库,即数据存储结构不同。详细阅读
6 、你怎么比较MongoDB、CouchDB及CouchBase?
MongoDB和CouchDB都是面向文档的数据库。MongoDB和CouchDB都是开源NoSQL数据库的最典型代表。 除了都以文档形式存储外它
们没有其他的共同点。MongoDB和CouchDB在数据模型实现、接口、对象存储以及复制方法等方面有很多不同。
细节可以参见下面的链接:
MongDB vs CouchDB
CouchDB vs CouchBase
7 、MongoDB成为最好NoSQL数据库的原因是什么?
以下特点使得MongoDB成为最好的NoSQL数据库:
面向文件的
高性能
高可用性
易扩展性
丰富的查询语言
6.32位系统上有什么细微差别?
journaling会激活额外的内存映射文件。这将进一步抑制 32 位版本上的数据库大小。因此,现在journaling在 32 位系统上默认是禁用的。
8 、journal回放在条目(entry)不完整时(比如恰巧有一个中途故障了)会遇到问题吗?
每个journal (group)的写操作都是一致的,除非它是完整的否则在恢复过程中它不会回放。
9 、分析器在MongoDB中的作用是什么?
MongoDB中包括了一个可以显示数据库中每个操作性能特点的数据库分析器。通过这个分析器你可以找到比预期慢的查询(或写操作);利用
这一信息,比如,可以确定是否需要添加索引。
10 、名字空间(namespace)是什么?
MongoDB存储BSON对象在丛集(collection)中。数据库名字和丛集名字以句点连结起来叫做名字空间(namespace)。
11 、 如果用户移除对象的属性,该属性是否从存储层中删除?
是的,用户移除属性然后对象会重新保存(re-save())。
12 、能否使用日志特征进行安全备份?
是的。
13 、允许空值null吗?
对于对象成员而言,是的。然而用户不能够添加空值(null)到数据库丛集(collection)因为空值不是对象。然而用户能够添加空对象{}。
14 、更新操作立刻fsync到磁盘?
不会,磁盘写操作默认是延迟执行的。写操作可能在两三秒(默认在 60 秒内)后到达磁盘。例如,如果一秒内数据库收到一千个对一个对象递
增的操作,仅刷新磁盘一次。(注意,尽管fsync选项在命令行和经过getLastError_old是有效的)(译者:也许是坑人的面试题??)。
15 、如何执行事务/加锁?
MongoDB没有使用传统的锁或者复杂的带回滚的事务,因为它设计的宗旨是轻量,快速以及可预计的高性能。可以把它类比成MySQL
MylSAM的自动提交模式。通过精简对事务的支持,性能得到了提升,特别是在一个可能会穿过多个服务器的系统里。
16 、为什么我的数据文件如此庞大?
MongoDB会积极的预分配预留空间来防止文件系统碎片。
17 、启用备份故障恢复需要多久?
从备份数据库声明主数据库宕机到选出一个备份数据库作为新的主数据库将花费 10 到 30 秒时间。这期间在主数据库上的操作将会失败--包括
写入和强一致性读取(strong consistent read)操作。然而,你还能在第二数据库上执行最终一致性查询(eventually consistent query)(在
slaveOk模式下),即使在这段时间里。
18 、什么是master或primary?
它是当前备份集群(replica set)中负责处理所有写入操作的主要节点/成员。在一个备份集群中,当失效备援(failover)事件发生时,一个另外
的成员会变成primary。
19 、什么是secondary或slave?
Seconday从当前的primary上复制相应的操作。它是通过跟踪复制oplog(local.oplog.rs)做到的。
20 、我必须调用getLastError来确保写操作生效了么?
不用。不管你有没有调用getLastError(又叫"Safe Mode")服务器做的操作都一样。调用getLastError只是为了确认写操作成功提交了。当
然,你经常想得到确认,但是写操作的安全性和是否生效不是由这个决定的。
21 、我应该启动一个集群分片(sharded)还是一个非集群分片的 MongoDB 环境?
为开发便捷起见,我们建议以非集群分片(unsharded)方式开始一个 MongoDB 环境,除非一台服务器不足以存放你的初始数据集。从非集
群分片升级到集群分片(sharding)是无缝的,所以在你的数据集还不是很大的时候没必要考虑集群分片(sharding)。
22 、分片(sharding)和复制(replication)是怎样工作的?
每一个分片(shard)是一个分区数据的逻辑集合。分片可能由单一服务器或者集群组成,我们推荐为每一个分片(shard)使用集群。
23 、数据在什么时候才会扩展到多个分片(shard)里?
MongoDB 分片是基于区域(range)的。所以一个集合(collection)中的所有的对象都被存放到一个块(chunk)中。只有当存在多余一个块的时
候,才会有多个分片获取数据的选项。现在,每个默认块的大小是 64Mb,所以你需要至少 64 Mb 空间才可以实施一个迁移。
24 、当我试图更新一个正在被迁移的块(chunk)上的文档时会发生什么?
更新操作会立即发生在旧的分片(shard)上,然后更改才会在所有权转移(ownership transfers)前复制到新的分片上。
25 、如果在一个分片(shard)停止或者很慢的时候,我发起一个查询会怎样?
如果一个分片(shard)停止了,除非查询设置了“Partial”选项,否则查询会返回一个错误。如果一个分片(shard)响应很慢,MongoDB则会等
待它的响应。
26 、我可以把moveChunk目录里的旧文件删除吗?
没问题,这些文件是在分片(shard)进行均衡操作(balancing)的时候产生的临时文件。一旦这些操作已经完成,相关的临时文件也应该被删
除掉。但目前清理工作是需要手动的,所以请小心地考虑再释放这些文件的空间。
27 、我怎么查看 Mongo 正在使用的链接?
db._adminCommand("connPoolStats");
28 、如果块移动操作(moveChunk)失败了,我需要手动清除部分转移的文档吗?
不需要,移动操作是一致(consistent)并且是确定性的(deterministic);一次失败后,移动操作会不断重试;当完成后,数据只会出现在新的分
片里(shard)。
29 、如果我在使用复制技术(replication),可以一部分使用日志(journaling)而其他部分则
不使用吗?
可以。
30 、当更新一个正在被迁移的块(Chunk)上的文档时会发生什么?
更新操作会立即发生在旧的块(Chunk)上,然后更改才会在所有权转移前复制到新的分片上。
31 、MongoDB在A:{B,C}上建立索引,查询A:{B,C}和A:{C,B}都会使用索引吗?
不会,只会在A:{B,C}上使用索引。
32 、如果一个分片(Shard)停止或很慢的时候,发起一个查询会怎样?
如果一个分片停止了,除非查询设置了“Partial”选项,否则查询会返回一个错误。如果一个分片响应很慢,MongoDB会等待它的响应。
33 、MongoDB支持存储过程吗?如果支持的话,怎么用?
MongoDB支持存储过程,它是javascript写的,保存在db.system.js表中。
34 、如何理解MongoDB中的GridFS机制,MongoDB为何使用GridFS来存储文件?
GridFS是一种将大型文件存储在MongoDB中的文件规范。使用GridFS可以将大文件分隔成多个小文档存放,这样我们能够有效的保存大文
档,而且解决了BSON对象有限制的问题。
35 、什么是NoSQL数据库?NoSQL和RDBMS有什么区别?在哪些情况下使用和不使用
NoSQL数据库?
NoSQL是非关系型数据库,NoSQL = Not Only SQL。
关系型数据库采用的结构化的数据,NoSQL采用的是键值对的方式存储数据。
在处理非结构化/半结构化的大数据时;在水平方向上进行扩展时;随时应对动态增加的数据项时可以优先考虑使用NoSQL数据库。
在考虑数据库的成熟度;支持;分析和商业智能;管理及专业性等问题时,应优先考虑关系型数据库。
36 、MongoDB支持存储过程吗?如果支持的话,怎么用?
MongoDB支持存储过程,它是javascript写的,保存在db.system.js表中。
37 、如何理解MongoDB中的GridFS机制,MongoDB为何使用GridFS来存储文件?
GridFS是一种将大型文件存储在MongoDB中的文件规范。使用GridFS可以将大文件分隔成多个小文档存放,这样我们能够有效的保存大文
档,而且解决了BSON对象有限制的问题。
38 、为什么MongoDB的数据文件很大?
MongoDB采用的预分配空间的方式来防止文件碎片。
39 、当更新一个正在被迁移的块(Chunk)上的文档时会发生什么?
更新操作会立即发生在旧的块(Chunk)上,然后更改才会在所有权转移前复制到新的分片上。
40 、MongoDB在A:{B,C}上建立索引,查询A:{B,C}和A:{C,B}都会使用索引吗?
不会,只会在A:{B,C}上使用索引。
41 、如果一个分片(Shard)停止或很慢的时候,发起一个查询会怎样?
如果一个分片停止了,除非查询设置了“Partial”选项,否则查询会返回一个错误。如果一个分片响应很慢,MongoDB会等待它的响应。
42 、分析器在MongoDB中的作用是什么?
分析器就是explain 显示每次操作性能特点的数据库分析器。通过分析器可能查找比预期慢的操作
43 、如果用户移除对象的属性,该属性是否从存储层中删除?
是的,用户移除属性然后对象会重新保存(re-save())。
44 、能否使用日志特征进行安全备份?
是的
45 、更新操作立刻fsync到磁盘?
一般磁盘的写操作都是延迟执行的
46 、如何执行事务/加锁?
因为mongodb设计就是轻量高性能,所以没有传统的锁和复杂的事务的回滚
47 、什么是master或primary?
当前备份集群负责所有的写入操作的主要节点,在集群中,当主节点(master)失效,另一个成员会变为master
48 、getLastError的作用
调用getLastError 可以确认当前的写操作是否成功的提交
49 、分片(sharding)和复制(replication)是怎样工作的?
分片可能是单一的服务器或者集群组成,推荐使用集群
50 、数据在什么时候才会扩展到多个分片(shard)里?
mongodb分片是基于区域的,所以一个集合的所有对象都放置在同一个块中,只有当存在多余一个块的时候,才会有多个分片获取数据的
选项
51 、 当我试图更新一个正在被迁移的块(chunk)上的文档时会发生什么?
会立即更新旧的分片,然后更改才会在所有权转移前复制到新的分片上
52 、 我怎么查看 Mongo 正在使用的链接?
53 、mongodb的结构介绍
数据库中存储的对象设计bson,一种类似json的二进制文件,由键值对组成
54 、数据库的整体结构
键值对–》文档–》集合–》数据库
55 、MongoDB是由哪种语言写的
MongoDB用c++编写的,流行的开源数据库MySQL也是用C++开发的。 C++ 1983 年发行是一种使用广泛的计算机程序设计语言。它是一种通
用程序设计语言,支持多重编程模式。
db._adminCommand("connPoolStats");
56 、MongoDB的优势有哪些
面向文档的存储:以 JSON 格式的文档保存数据。
任何属性都可以建立索引。
复制以及高可扩展性。
自动分片。
丰富的查询功能。
快速的即时更新。
来自 MongoDB 的专业支持。、
57 、什么是集合
集合就是一组 MongoDB 文档。它相当于关系型数据库(RDBMS)中的表这种概念。集合位于单独的一个数据库中。一个集合内的多个文
档可以有多个不同的字段。一般来说,集合中的文档都有着相同或相关的目的。
58 、什么是文档
文档由一组key value组成。文档是动态模式,这意味着同一集合里的文档不需要有相同的字段和结构。在关系型数据库中table中的每一条记
录相当于MongoDB中的一个文档。
59 、什么是”mongod“
mongod是处理MongoDB系统的主要进程。它处理数据请求,管理数据存储,和执行后台管理操作。当我们运行mongod命令意味着正在
启动MongoDB进程,并且在后台运行。
60 、"mongod"参数有什么
传递数据库存储路径,默认是"/data/db"
端口号 默认是 "27017"
61 、什么是"mongo"
它是一个命令行工具用于连接一个特定的mongod实例。当我们没有带参数运行mongo命令它将使用默认的端口号和localhost连接
62 、MongoDB哪个命令可以切换数据库
MongoDB 用use+ 数据库名称 的方式来创建数据库。use会创建一个新的数据库,如果该数据库存在,则返回这个数据库。
63 、什么是非关系型数据库
非关系型数据库是对不同于传统关系型数据库的统称。非关系型数据库的显著特点是不使用SQL作为查询语言,数据存储不需要特定的表格
模式。由于简单的设计和非常好的性能所以被用于大数据和Web Apps等
64 、非关系型数据库有哪些类型
-Key-Value 存储 Eg:Amazon S3
图表 Eg:Neo4J
文档存储 Eg:MongoDB
基于列存储 Eg:Cassandra
65 、为什么用MOngoDB?
架构简单
没有复杂的连接
深度查询能力,MongoDB支持动态查询。
容易调试
容易扩展
不需要转化/映射应用对象到数据库对象
使用内部内存作为存储工作区,以便更快的存取数据。
66 、在哪些场景使用MongoDB
>use database_name
大数据
内容管理系统
移动端Apps
数据管理
67 、MongoDB中的命名空间是什么意思?
MongoDB内部有预分配空间的机制,每个预分配的文件都用 0 进行填充。
数据文件每新分配一次,它的大小都是上一个数据文件大小的 2 倍,每个数据文件最大2G。
MongoDB每个集合和每个索引都对应一个命名空间,这些命名空间的元数据集中在16M的*.ns文件中,平均每个命名占用约 628 字节,也
即整个数据库的命名空间的上限约为 24000 。
如果每个集合有一个索引(比如默认的_id索引),那么最多可以创建 12000 个集合。如果索引数更多,则可创建的集合数就更少了。同时,
如果集合数太多,一些操作也会变慢。
要建立更多的集合的话,MongoDB 也是支持的,只需要在启动时加上“--nssize”参数,这样对应数据库的命名空间文件就可以变得更大以便
保存更多的命名。这个命名空间文件(.ns文件)最大可以为 2G。
每个命名空间对应的盘区不一定是连续的。与数据文件增长相同,每个命名空间对应的盘区大小都是随分配次数不断增长的。目的是为了平
衡命名空间浪费的空间与保持一个命名空间数据的连续性。
需要注意的一个命名空间$freelist,这个命名空间用于记录不再使用的盘区(被删除的Collection或索引)。每当命名空间需要分配新盘区
时,会先查看$freelist是否有大小合适的盘区可以使用,如果有就回收空闲的磁盘空间。
68 、哪些语言支持MongoDB?
C
C++
C#
Java
Node.js
Perl
Php 等
69 、在MongoDB中如何创建一个新的数据库
MongoDB 用 use + 数据库名称 的方式来创建数据库。use^ 会创建一个新的数据库,如果该数据库存在,则返回这个数据库。
70 、在MongoDB中如何查看数据库列表
使用命令"show dbs"
71 、MongoDB中的分片是什么意思
分片是将数据水平切分到不同的物理节点。当应用数据越来越大的时候,数据量也会越来越大。当数据量增长时,单台机器有可能无法存储
数据或可接受的读取写入吞吐量。利用分片技术可以添加更多的机器来应对数据量增加以及读写操作的要求。
72 、如何查看使用MongoDB的连接Sharding - MongoDB Manual21.如何查看使用
MongoDB的连接
使用命令"db.adminCommand(“connPoolStats”)"
73 、什么是复制
复制是将数据同步到多个服务器的过程,通过多个数据副本存储到多个服务器上增加数据可用性。复制可以保障数据的安全性,灾难恢复,
无需停机维护(如备份,重建索引,压缩),分布式读取数据。
74 、在MongoDB中如何在集合中插入一个文档
要想将数据插入 MongoDB 集合中,需要使用insert()或save()方法。
>use mydb
switched to db mydb
>show dbs
>db.adminCommand(“connPoolStats”)
75 、在MongoDB中如何除去一个数据库Collection Methods24.在MongoDB中如何除去一
个数据库
MongoDB 的dropDatabase()命令用于删除已有数据库。
76 、在MongoDB中如何创建一个集合。
在 MongoDB 中,创建集合采用 db.createCollection(name, options) 方法。options是一个用来指定集合配置的文档。
77 、在MongoDB中如何查看一个已经创建的集合
可以使用show collections 查看当前数据库中的所有集合清单
78 、在MongoDB中如何删除一个集合
MongoDB 利用db.collection.drop()来删除数据库中的集合。
79 、为什么要在MongoDB中使用分析器
数据库分析工具(Database Profiler)会针对正在运行的mongod实例收集数据库命令执行的相关信息。包括增删改查的命令以及配置和管理
命令。分析器(profiler)会写入所有收集的数据到 system.profile集合,一个capped集合在管理员数据库。分析器默认是关闭的你能通过per
数据库或per实例开启。
80 、MongoDB支持主键外键关系吗
默认MongoDB不支持主键和外键关系。 用Mongodb本身的API需要硬编码才能实现外键关联,不够直观且难度较大。可以参考以下链接
81 、MongoDB支持哪些数据类型
String
Integer
Double
Boolean
Object
Object ID
Arrays
Min/Max Keys
Datetime
Code
Regular Expression等
82 、为什么要在MongoDB中用"Code"数据类型
"Code"类型用于在文档中存储 JavaScript 代码。
83 、为什么要在MongoDB中用"Regular Expression"数据类型
"Regular Expression"类型用于在文档中存储正则表达式
84 、为什么在MongoDB中使用"Object ID"数据类型
>db.collectionName.insert({"key":"value"})
>db.collectionName.save({"key":"value"})
>db.dropDatabase()
>db.createCollection("collectionName")db .createCollection() - MongoDB Manual>db.createCollection("
>show collections
>db.CollectionName.drop()
"ObjectID"数据类型用于存储文档id
85 、如何在集合中插入一个文档
要想将数据插入 MongoDB 集合中,需要使用insert()或save()方法。
86 、"ObjectID"有哪些部分组成
一共有四部分组成:时间戳、客户端ID、客户进程ID、三个字节的增量计数器
_id 是一个 12 字节长的十六进制数,它保证了每一个文档的唯一性。在插入文档时,需要提供_id。如果你不提供,那么 MongoDB 就会
为每一文档提供一个唯一的 id。_id的头 4 个字节代表的是当前的时间戳,接着的后 3 个字节表示的是机器 id 号,接着的 2 个字节表示
MongoDB 服务器进程 id,最后的 3 个字节代表递增值。
87 、在MongoDb中什么是索引
索引用于高效的执行查询.没有索引MongoDB将扫描查询整个集合中的所有文档这种扫描效率很低,需要处理大量数据。索引是一种特殊的
数据结构,将一小块数据集保存为容易遍历的形式。索引能够存储某种特殊字段或字段集的值,并按照索引指定的方式将字段值进行排序。
88 、如何添加索引
使用db.collection.createIndex()在集合中创建一个索引
89 、用什么方法可以格式化输出结果
使用pretty() 方法可以格式化显示结果
90 、如何使用"AND"或"OR"条件循环查询集合中的文档
在find()方法中,如果传入多个键,并用逗号(,)分隔它们,那么 MongoDB 会把它看成是 AND 条件。
若基于 OR 条件来查询文档,可以使用关键字 $or 。
91 、在MongoDB中如何更新数据
update()与save()方法都能用于更新集合中的文档。update()方法更新已有文档中的值,而save()方法则是用传入该方法的文档来替
换已有文档。
92 、如何删除文档
MongoDB 利用 remove() 方法 清除集合中的文档。它有 2 个可选参数:
deletion criteria:(可选)删除文档的标准。
justOne:(可选)如果设为 true 或 1 ,则只删除一个文档。
>db.collectionName.insert({"key":"value"})
>db.collectionName.save({"key":"value"})
>db.collectionName.createIndex({columnName:1})
>db.collectionName.find().pretty()
>db.mycol.find({key1:value1, key2:value2}).pretty()
>db.mycol.find(
{
$or: [
{key1: value1}, {key2:value2}
]
}
).pretty()
>db.collectionName.update({key:value},{$set:{newkey:newValue}})
>db.collectionName.remove({key:value})
Version Feature
Spring
2.5
发布于 2007 年。这是第一个支持注解的版本。
Spring
3.0
发布于 2009 年。它完全利用了 Java5 中的改进,并为 JEE6 提供了支 持
Spring
4.0
发布于 2013 年。这是第一个完全支持 JAVA8 的版本。
Spring
5.0
Spring Framework 5.0的最大特点之一是 响应式编程(Reactive Programming) 。 响应式编程核心功能和对响应式
endpoints的支持可通过Spring Framework 5.0中获得。
93 、在MongoDB中如何排序
MongoDB 中的文档排序是通过sort()方法来实现的。sort()方法可以通过一些参数来指定要进行排序的字段,并使用 1 和 -1 来指定排
序方式,其中 1 表示升序,而 -1 表示降序。
94 、什么是聚合
聚合操作能够处理数据记录并返回计算结果。聚合操作能将多个文档中的值组合起来,对成组数据执行各种操作,返回单一的结果。它相当
于 SQL 中的 count(*) 组合 group by。对于 MongoDB 中的聚合操作,应该使用aggregate()方法。
95 、在MongoDB中什么是副本集
在MongoDB中副本集由一组MongoDB实例组成,包括一个主节点多个次节点,MongoDB客户端的所有数据都写入主节点(Primary),副节
点从主节点同步写入数据,以保持所有复制集内存储相同的数据,提高数据可用性。