[ 
https://issues.apache.org/jira/browse/KYLIN-4654?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17192166#comment-17192166
 ] 

chuxiao commented on KYLIN-4654:
--------------------------------

更新方案,重新设计更新实体操作。

针对一般实体的更新,先更新存储再让缓存可读。
单个服务进程,先更新存储,成功了再更新缓存。潜在的风险,是后更新缓存的被前置更新的覆盖。对表,model,cube来说,更新存储和更新缓存的操作必须加锁。
多个服务进程,收到实体更新通知,为避免潜在的多个并发“读存储-写map”的顺序和服务自身的“写存储-写map”的不一致,必须加锁,加锁的最小单位是资源本身。
instance对象当reload会new新的,所以更新存储和缓存时,应该跳出实例,对资源的唯一路径加锁。
对于new实体操作,并发只允许一个保存成功。
udpate实体操作,单一操作要么全部成功要么全部失败。如果直接在旧instace上更新,可能会保存另一个更新操作的一半变更。要么更新实例属性时就加资源路径锁,要么clone实例更新,更新成功后再更新map映射。
前者的风险是更新属性后可能还有一堆其他逻辑,当后续逻辑要更新其他实体时有死锁风险。后者在同一个服务内更容易更新失败,如果要提高操作成功率需要reload重新更新cas更多次,并且对于实体整体的更新无法reload。并发操作是少见的,个人倾向cas。
再加上通过haproxy请求多个服务进程的场景,有2点需要注意。1.可能并发有冲突cas失败,进程内的锁不管用。全局锁,或者cas失败操作失败,或者cas失败了reload重试cas。2.连续操作时前置操作返回成功了,新操作请求的服务进程还没更新对应的缓存,可能找不到元数据。
考虑实际场景,单个表,model,cube自身的并发创建/更新,一般只出现于同一个请求连续发了多次,并发创建/更新只成功一个影响并不大。所以实现可以clone/reload/new的基础上修改,再cas,失败就直接操作失败。
对于prj更新table/model/cube/其他属性,如果要允许并发,需要拆project元数据为多个。如果保持现在的prj整体为最小粒度,在并发时必然有冲突。对更新其他属性,直接失败没问题。但更新prj的子元素列表失败,因为已经保存子元素了,直接操作失败会留有子元素的脏数据。这本质是同时更新子元素和prj的操作原子性问题。没有事务的存储引擎是无法保证多个更新的原子性的,取舍为reload
 prj并更新子元素cas,重试几次后还是失败则操作失败。如果真的由于存储引擎问题或并发太高问题产生子元素的脏数据,概率很低,用清理工具删除元数据即可。
再就是更新segment,这个可以采用prj更新子元素相同逻辑来处理,目前应该就是这么做的。

对于连续操作在多个服务进程上的串行,如果发现依赖实体还无缓存,可以尝试主动reload一次依赖实体,依然不存在再报错。如果更新依赖实体再来新建实体,由于缓存还未刷新导致新建实体检查正确性失败,非常规操作,直接失败让客户端重试即可。
对lru2cache,资源缓存换了对象实例,可能会影响lru2cache映射。但考虑还没被引用的才可以直接修改信息,所以收口lru2cache的变化,只有在会影响查询路由的cube变化时再统一更新,其他时候直接读即可。

对于其他读缓存还未更新的场景,直接按读缓存处理,潜在风险目前只想到当依赖实体被删除时基于依赖并发创建实体(例如删除model的同时基于该model并发创建cube)可能出现问题。考虑这是非常规操作,依赖都要删除了还要基于依赖去创建本身也是有问题的,后果是新创建的实体不可用,不影响已有查询和其他实体创建,影响可控,用清理工具删除元数据即可。

> new metadata read/write and reload mechanism
> --------------------------------------------
>
>                 Key: KYLIN-4654
>                 URL: https://issues.apache.org/jira/browse/KYLIN-4654
>             Project: Kylin
>          Issue Type: Improvement
>            Reporter: chuxiao
>            Priority: Major
>         Attachments: 优化方案.docx, 现有代码梳理.docx
>
>
> support when there are 10,000 cube in one cluster one project, and 1000 cubes 
> continue update,still can create cube  and query  



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to