mcrouter 简介及路由规则
mcrouter�
pool
sharded pool
通过对key进行hash到不同节点,减少每个节点存储的数据量,当集群数据量大时,需要通过分片来减少单节点容量
replicated pool
用于请求量大且读多写少的场景,pool里面的每个节点保存同样的数据,通过随机选择读节点分散读请求减少单节点压力,如果读请求失败,则会自动选取其他节点进行重试。
- du请求从pool里随机选取一个节点
- 写和删除操作需要复制到集群的所有节点
示例
{
"pools": {
"A": {
"servers": [
// hosts of replicated pool, e.g.:
"127.0.0.1:12345",
"[::1]:12346"
]
}
},
"route": {
"type": "OperationSelectorRoute",
"operation_policies": {
"add": "AllSyncRoute|Pool|A",
"delete": "AllSyncRoute|Pool|A",
"get": "LatestRoute|Pool|A",
"set": "AllSyncRoute|Pool|A"
}
}
}
Routing
prefix routing
前缀路由,通过给key设置不同的前缀路由到不同的pool,通过给同种类型的key设置一样的前缀,写入同一套集群,增加集群内部key的内聚度。
{
"pools": {
"workload1": { "servers": [ /* list of cache hosts for workload1 */ ] },
"workload2": { "servers": [ /* list of cache hosts for workload2 */ ] },
"workload3": { "servers": [ /* list of cache hosts for workload3 */ ] },
"common_cache": { "servers": [ /* list of cache hosts for common use */ ] }
},
"route": {
"type": "PrefixSelectorRoute",
"policies": {
"a": "PoolRoute|workload1",
"b": "PoolRoute|workload2",
"ab": "PoolRoute|workload3"
},
"wildcard": "PoolRoute|common_cache"
}
}
shadowing
流量镜像复制,通过将线上流量镜像复制到test集群,进行新功能的验证。下面配置示例将请求到线上节点1,2的请求总数的105复制到test集群,以集群test集群新功能的验证。
{
"pools": {
"production": {
"servers": [ /* production hosts */ ]
},
"test": {
"servers": [ /* test hosts */ ]
}
},
"route": {
"type": "PoolRoute",
"pool": "production",
"shadows": [
{
"target": "PoolRoute|test",
// shadow traffic that would go to first and second hosts in 'production' pool
// note that the endpoint is non-inclusive
"index_range": [0, 2],
// shadow requests for 10% of keys based on key hash
"key_fraction_range": [0, 0.1]
}
]
}
}
cold cache warm up
缓存预热,当新的缓存实例被加入进群当中的时候,由于节点数据为空,为造成客户端大量miss,影响客户端的响应耗时,甚至大量miss还会造成缓存雪崩打挂后端存储。
通过设置cache warm up,客户端的写和删除请求会被直接发往新增的节点,对于读请求,如果请求节点miss,则会从warm集群里面读取数据并返回给客户端,同时从warm集群读取到的数据会异步写入cold集群,通过从warm集群读取数据,减少直接回源后端存储给村春造成压力。
{
"pools": {
"cold": { "servers": [ /* cold hosts */ ] },
"warm": { "servers": [ /* warm hosts */ ] }
},
"route": {
"type": "WarmUpRoute",
"cold": "PoolRoute|cold",
"warm": "PoolRoute|warm"
}
}
multi broadcast
多机房|多数据中心 场景下,一个业务往往在不同的数据中心拥有不同的集群,通过broadcast,可以将对key的修改操作广播到所有集群,保证多数据中心的业务数据尽可能一致。
对于请求量大的业务,往往也需要对业务进行多集群的部署,然后不同的业务依赖方使用不同的集群,从而达到业务资源的隔离 。比如账号系统,针对电商,游戏,直播等不同业务场景,给不同业务部署独立的业务集群,从而达到业务资源的隔离以及最小化故障影响范围。这种情况下,对于账号信息的更新就需要同步到所有的集群保证数据的正确性。
Two level caching
二级缓存,第一级缓存提供较小的容量以及更小的响应耗时,第二级缓存则可提供更大的容量。类似于操作系统的L1,L2缓存。
二级缓存的读逻辑为:
- 从一级缓存读取数据
- 如果miss,则从二级缓存读取数据
- 如果二级缓存读取命中,则讲数据写回一级缓存
二级缓存更新逻辑,二级缓存的数据更新根据是否容忍脏数据分为两种:
允许短暂脏数据
在允许短暂脏数据的情况下,通过给local cache设置较小的过期时间,来达成脏数据的自动过期,数据更新时,只更新local cache和reomte cache。不同节点间的local cache可能存在数据的短暂不一致。通过较小的expire自动清理
广播更新操作
对于不容许脏数据的情况下,对于数据更新,则需要将更新操作复制到所有的local cache,保证不同local cache间数据的一致性。
key syntax
- Prefix
- hash tag
- Admin requet
mcrouter 可以的解析规则分为前缀以及keyhash标识。通过设置前缀规则,将key写入不同的集群,通过设置hash tag则将同一类型的key写入同一后端节点。对于前缀,有一种特殊情况 admin request. 通过前缀__mcrouter_-
标识为管理员请求。该类型请求不会被转发到任意后端节点。
// 该key的router规则为 /a/b/ 根据/a/b/ 选择路由到指定的集群,hash key则为 foo:key ,进行hash计算得到指定的后端节点。
key: /a/b/foo:key|#|etc
route handle
AllAsyncRoute
发送请求到所有children route,不等待children的响应立即返回到客户端
AllFastestRoute
立即发送请求到所有route,只要有一个route返回成功则立即响应client,如果所有的route都返回失败,则返回最后一个错误给客户端。
AllInitailRoute
立即发送请求到所有route,等到第一个route返回后才响应客户端请求,其他route的请求在后台异步处理。
AllMajorityRoute
立即发送请求到所有route,只有过半数节点返回成功后,才返回。(如果没有过半route返回成功,则返回以后一个失败的响应。)剩余的route请求后台异步完成。
AllSyncRoute
等到所有route的返回,只要有一个route返回错误,则该次请求返回错误给客户端。
DevNullRoute
和NullRoute 一直,但是包含统计信息。
ErrorRoute
立即返回失败,同时可以置顶返回失败的内容 ErrorRoute|MyErrorValue
FailoverRoute
依次请求route list里面的route,直到有route返回成功。可以定义每个操作的错误信息
{
"gets": [ "connect_timeout", "timeout", "connect_error", "tko" ],
"updates": [], // empty array: will not failover.
// "deletes" is missing, default behavior (all errors) will be assumed.
}
如上,当gets操作返回connect_timeout timeout错误时,则进入failover继续请求下一个route
HashRoute
通过hash选择route
HostIdRoute
通过host id进行hash选择route
LatencyInjectionRoute
通过对route进行延迟注入进行故障模拟,通过设置 before_latency_ms
和after_latency_ms
来定义route的延迟时间,发往改route的请求会自动延迟以模拟网络异常的场景
LatestRoute
通过设置failover_count来对route进行快速failover,如果某个route的fail_count超过配置的值,则请求到这个route的请求会立即进入failover流程
LoadBalancerRoute
支持两种负载均衡选择,加权随机算法以及二选一随机算法 通过对route负载的定期计算,来选择负载最低的route
MigrateRoute
将from
集群的数据迁移到to
集群 ,迁移步骤:
- 开始迁移前,将所有请求写入from 集群
- [start_time,start_time+interval] ,除了删除操作的所有请求发往from,delete同时发往from和to
- [start_time+interval,start_time+2*interval]除了delete,所有请求发往to集群,delete同时发到from和to
- [start_time+2*interval,]所有请求发到to集群,迁移结束。
MissFailoverRoute
依次向route发送请求知道key命中
NullRoute
对于所有请求,立即返回not found
PrefixSelectorRoute
根据key的前缀选择不同route
RandomRoute
从route list里随机选择一个route