mndb 工作机制

mndb - 一个多协议网络数据库管理

介绍
nmdb是一个简单的快速缓存和受控网络数据库.它允许应用以一种非常简单的方法使用集中,分享式的缓存和数据库。它以键值对存储,并且每一个键只有一个相关联的值。
这个文档解释服务端内部是如何工作的,和它为什么要那样工作。
网络接口
服务端与客户端通过信息来通信。它可以通过TIPC,TCP,UDP或者SCTP来传递。消息被设计限制大小为64K,也是在TIPC的限制范围内.
 TIPC是一个完全的无连接,并且使用一个由TIPC提供的可靠数据包层。网络协议在另一个文档中有详细说明,这里将不会分析它。
交互非常简单:客户发送一个请求消息动作,服务端响应它。这里的每个请求只有一个消息,并且每一个响应只包含一个消息。这利用了键和值的大小限制,每一个键或值都是定大小的64K,而且键和值加起来也是受限的。这意味着每一个键或值都不得超过64K,并且它们之和也不能超过64K.
下面是客户端向服务端发送的几种请求:
通过键获取值
   根据给定的键找到对应的值。如果键在缓存中存在,则立即返回。否则,将执行一个数据库查询操作。
设置键值对
   存储一个键值对到数据库中。
删除键值对
   从数据库中删除键和键所对应的值
用新值替换旧值
    做一个比较和替换操作。使用旧值与数据库中的值进行比较,如果匹配上则用新值替换旧值。
追加
    在一个键所对应的值后面追加值。

请求可以通过标识来影响它们(服务端)的行为.cache-only标识会使服务端操作只影响缓存但不影响数据库。sync标识使服务端一直等待直到请求响应完成,而不是在请求正在排队处理的同时立即返回响应(可能持久化这种操作在处理队列中,并不会等待处理完后再返回)。不是所有的标识对所有的操作都是有意义的,细节请参考库文档.

正如你看到的,它可以只操作缓存,而完全忽略数据库。它与memcached所做的非常相似。要注意的是那样做的缺点是它可能影响缓存,但省去了同步数据库的操作。You can only do this if you mix a cache-only set with a normal set, which is hard to miss, so it's unlikely you will do this by mistake.

请求处理
服务端由两种线程组成:主线程(事件线程)和数据库线程。
主线程是基于事件的,使用libevent进行网络推送,并且处理输入的消息。每个消息通过一个初始化解码阶段,并且还依赖于请求命令,不同的方法被调用,通过的所有请求都会执行一样的基本步骤。当一个操作任务出现

数据库线程处理一个操作的操作任务队列。操作由主线程添加,由数据库线程移除。当一个操作出现时,它通过调相应的数据库方法来处理,然后回去等待。这个操作是完全同步的,并且所有操作都是按顺序执行的。

当接到一个请求后,将会执行如下步骤:
1.在解析消息的时候做一些基本的健全性检查。
2.遵照缓存行事。如果它是一个缓存操作,则发送响应,操作结束。
3.在操作队列中排队请求。
4.如果它是一个异步操作,则发送响应,操作结束。
5.如果不是,通知数据库它有任务要做,操作结束。

注意对于异步操作,通知不会发送。这是因为发送通知是一个大动作,为了避免以减少延时。它也意味着数据库在通知操作上面可能是要花一点时间,但那通常不会是一个问题(毕竟,那也是为什么请求首先是异步的).被选择的通知方法是一个有条件的互斥体,如果队列是空时数据库线程会一直等待。

尽管一些操作是异步的,但他们总是按顺序处理的。如果一个应用对同一个数据发起了两个操作,他们被保证按顺序完成。这就归避了在删除或设置后获取问题,使得用数据加后使应用程序复杂化。

数据库线程
这里只有一个数据库线程,使得总体设计更简单(这里没有多个操作的竞争,因为它们是按顺序执行的),但降低了潜在的同步性能。

从上述的请求队列中取出来的请求被处理完毕,并且遵照数据库行事,这包括依赖请求操作调用后台的get,set或del.然后,如果操作是同步的,将会向客观户端发送一个响应。

被动模式
服务有个特殊模式,被动模式,它也会监听请求,依赖内部机制处理请求,但从不发送任何响应。它被用作冗余目的,允许管理员有一个最新的数据库副本以防主服务出现问题。

如果使用TIPC,它只要它有意义。因为它是多点传送消息的。
实现起来很简单,因为代码路径是完全一样的,唯一的区别是跳过了响应,所以它可以通过被动设置来完成。

实时将一个服务端从被动切换成活动状态(或者相反)只要在运行时发送一个SIGUSR2给服务就可以了。

缓存层
缓存层由一个改良的hashtable实现的,它使得移除变得高效和廉价.
hashtable非常普通:几个桶(大小在初始化时设定的),每个桶包含了一个装有分配对象的链接列表.
下面是一些窍门:
1.为了保持在缓存中的对象数量的范围,每个链接列表中的元素数量被限制为4个。
2.无论何时一个查询发起后,被匹配的实体将上升到包含它的链表的最上面。
3.当插入一个新元素到结存后,它总是插入到列表的最上面,作为第一个元素。
4。当链表的元素个数超过限制时,最底下元素被移除。

这就很自然的将LRU(最近最少使用)方法应用到每一个列表中,对于这种缓存是非常合适的。链表的长度要足够短以保证快速查找,但还要保证足够长为了使得LRU机制能够有效。

 

原文:http://blitiri.com.ar/p/nmdb/doc/design.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值