亿方云面试经验(后台开发工程师实习)
class Singleton
{
public:
static Singleton &Instance(){ //1
if(!m_pInstatnce){ //2
Lock(m_mutex) //3
If(!m_pInstance) //4
m_pInstance = new Singleton;//5
UnLock(m_mutex); //6
}
return *m_pInstance; //7
}
private:
static volatitle Singleton *m_pInstatnce; //8
private:
Singleton(); //9
Singleton(const Singleton&); //10
Singleton& operator=(const Singleton&); //11
~Singleton(); //12
}
Singleton *Singleton:m_pInstatnce = NULL; //13
1、 可拓展性 :可以以最小的代价、无须停机的方式增加存储系统的容量。一些情况下我们需要快速增加系统的容量,并且能够自动负载、利用到这些新的硬件设备。
2、 高写入吞吐量 :大多数应用都需要存储巨大量的数据,这就要求很高的写入吞吐量。
3、 单个 data center 内高性能、低延迟的强一致性 :一些重要的应用、比如消息、要求很强的单个数据中心内的一致性,这些需求很直观来自于用户需求,比如展示在主页的“未读消息”的数目和 inbox 页面显示的消息就应当是高度一致的。尽管全局强一致性的分布式系统几乎是不可能的,但是一个系统至少能够提供在单个数据中心内的强一致性,这能够带来很好的用户体验。
4、 高效的随机读取性能 :尽管应用层的缓存技术 (不管是嵌入式的还是 memcached 方式) 被广泛应用,但是很多访问仍然没办法命中缓存,需要后端的存储系统来处理,Hbase 随机读取性能很稳定。MySQL 在随机读取方面非常优秀,但如果 Hbase 结合分布式缓存 MemeCached 或者 MemBase,那么其读取性能就可以和 MySQL 比肩了。
5、 高可用性以及灾难恢复 :我们需要提供给用户高度可用的服务,不管是遇到计划中的事件(比如软件升级、或者硬件 / 容量的增加),还是遇到一些计划之外的事件(比如硬件失效)。我们也需要能够容许数据中心的一些数据丢失,能够在合理的时间范围内切换到其他数据中心来为用户提供服务。
6、 故障隔离 :我们在大量的 MySQL 数据库上的应用经验表明,故障隔离是非常关键的。单个数据库可以 down 掉,但是仅只有很小一部分用户会被这样的事件影响。类似地,在我们的 Hadoop 存储中,单个磁盘故障仅只会影响到一小部分数据,而且系统可以很快恢复。
7、 原子的“读 - 修改 - 写”原语 :原子的计数器和检查并设置 (checkand set、或者称 compare and swap) 等 API 在构建无锁的并发应用时非常有用,可以帮助用户有效地解决多线程竞争造成的很多问题。
8、 范围扫描 :一些应用要求特定范围内的行的集合的高效检索。例如,给定用户的最近 100 条消息的检索。
1、 可拓展性
虽然所有 NoSQL 数据库都承诺可拓展性,但是面对挑战是水平却不尽相同。
BigTable 的相似产品 Hbase 和 Hypertable 暂时处于领先地位,内存存储 (Membase 或 Redis) 和文档数据库 (MongDB 或 CouchBase) 紧随其后,他们之间的差异随着数据量的增大而被无限放大,特别是到了 PB 级以后。
拓展性方面 Hbase 具备天生的优势,支持自动负载均衡,故障转移,压缩和单服务器多分片,而且 Hbase 和 HDFS 配合的非常好,HDFS 能够通过复制和自动平衡轻松容纳跨越多个服务器的大文件。
所以所如果需要极端拓展性的话,列族 NoSQL 是最好的选择。
但是话又说回来,如果你的大量数据会以惊人的快节奏出现,例如一些实时的交易数据或者广告点击追踪数据,那么单靠列式存储无法提供完美的解决方案。这个时候你需要一些更加轻快、既支持快速读写、又支持实时处理的存储,没有什么比在内存里面处理数据更快了,所以你可以在 Hbase 前面搭配上 MongDB/Redis 来进行实时数据处理以及实时的数据挖掘等。其他一些实时性不是非常高的批量查询和数据挖掘可以利用 Mapreduce 在 Hbase 上进行。
2、 事务完整性和一致性
Hbase 和 Hypertable 提供行级的原子更新以及一致性状态,MongDB 提供文档级别的原子更新,Cassandra 只能提供最终一致性。
但是事务的要求并不是必须的,许多数据,比如网络流量日志,社交网络状态更新 (微博等),广告点击,道路交通数据,交易数据和游戏分数等是一次写、多次读,这样的数据对事务的需求有限,甚至没有。
有些数据虽然已更新和删除,但是修改通常只限于单记录而非数据集的某个范围,有时更新非常频繁且涉及范围操作。如果范围操作很常见并且需要保持更新的一致性,那么 RDBMS 才是最佳选择,如果单个条目的原子性已经足够,那么列式数据库、文档数据库和部分键 / 值存储都可以。如果需要事务完整性但是可以容纳暂时的窗口不一致,那么最终一致性存储也是不错的选择。
3、 数据模型
MongDB 支持类 SQL 查询、基本的关系型引用和数据库对象,如果使用 NoSQL 的主要原因是可以使用宽松的数据结构,那么 MongDB 肯定是开始使用 NOSQL 的最佳选择。
很多 Web 为中心的业务都开始使用 MongDB,主要是因为它支持灵活的数据模型 (弱 Schema),同时能够提供快速的读写能力。(现在敏捷开发很重要、MongoDB 能更快地开发应用程序。一个明显的原因是 MongoDB 没有固定的 Schema,所有花在提交、沟通和实施 Schema 变更的时间都省下来了)
此外 MongDB 对 Web 框架的支持非常好,比如 Spring、Rails 等。
最后要说明的是,MongDb 非常容易上手,学习周期很短。
4、 查询支持
挑选 NoSQL 主要考虑的因素除了存储,还有查询。
MongDB 和 Redis 的查询能力比较强。
像 MongDB 的查询,与 SQL 相似,语法简单,容易学习。MongoDB 支持范围查询,正则表达式查询,对子文档内属性的查询,可以取代原来大多数任务的 SQL 查询。
像 Redis 的查询,查询方法很全,命令文档也很丰富。
Hbase 只支持基于 Rowkey 的单条记录查找、基于 Rowkey 的范围查找以及全表扫描。
要注意的是几乎所有 NoSQL 存储都不支持表之间的 join 操作。
提到查询不得不提到索引,MongDB 本身支持二级索引,Hbase 不支持二级索引,但是现在也有很多方法 (最常见是借助协处理器) 可以帮助 Hbase 实时建立二级索引。
5、 性能
(1) 50/50 读和更新、即读少写多。
Cassandra 最优秀,每秒执行超过 1W 次操作,平均读延迟只有 25ms、更新性能更好只有 10ms。
Hbase 紧随其后。至于 MySQL,每秒执行 4000 左右操作的时候才和上面两个有可比性,超过 5000 之后延迟迅速攀升。
(2) 95/5 读和更新、即读多写少。
还是 Cassandra 最优秀。
列式存储连续范围的读取性能非常优秀,这证明和 Hbase 批量读写的性能非常好。
Hbase 表现非常稳定,与每秒操作数无关,5% 的更新在 Hbase 里面几乎没有延迟。
只读情况下 MySQL 性能最好,可能与缓存有关。
如果结合分布式缓存 MemeCached 或者 MemBase,那么 Hbase 的读取性能就可以和 MySQL 比肩了。
假设原来链表为 A1 -> A2 ->... -> An,新拷贝链表是 B1 -> B2 ->...-> Bn。
为了能够快速的找到 pRand 指向的节点,并把对应的关系拷贝到 B 中。我们可以将两个链表合并成
A1 -> B1 -> A2 -> B2 -> ... -> An -> Bn。
从 A1 节点出发,很容易找到 A1 的 pRand 指向的节点 Ax, 然后也就找到了 Bx,将 B1 的 pRand 指向 Bx 也就完成了 B1 节点 pRand 的拷贝。依次类推。
当所有节点的 pRand 都拷贝完成后,再将合并链表分成两个链表就可以了。