-
Notifications
You must be signed in to change notification settings - Fork 316
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
使用interface自定义好友列表、群列表、群成员列表存储 #249
Comments
考虑到正常人应该没有这么多群,建议把好友放内存,群联系人列表可以即时获取。QQ貌似也是这样处理的。2022年2月3日 20:01,千橘 雫霞 ***@***.***>写道:
是否考虑可用性?
个人认为采用非内存存储,可能增加不确定性,加大外部风险,甚至带来安全问题
—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you are subscribed to this thread.Message ID: ***@***.***>
|
这其实是可以考虑的方案, 因为目前内存绝大部分都是 群 好友 缓存使用的, 如果能持久化这部分数据确实可以大幅度降低内存使用 |
我认为是超前优化。 好友、群列表属于高频热点数据例,每次接收群消息时,会调用 倘若您的群活跃度高、数量多,使用磁盘存储上述数据可能造成不小的压力。 内存存储应该是当下的最优解 个人认为,提供其他方式存储热点数据只是转移了压力,并无多大的收益 |
不一定用磁盘,也可以考虑 Redis 这些缓存,interface 只是一种灵活的方式,允许自定义如何存储数据 FindGroup 现在是遍历 slice,如果改成 K-V 形式(比如 |
不是很明白,Redis 与 MiralGo 里直接存储有何不同,提供了何种能力,请指教 |
从进步角度来说,提供这样的接口确实能为 MiraiGo 提供更高级、更全面自定义的实现,无可厚非 但从普罗大众角度来说,我认为绝大多数人应该会选择直接用内存存储数据。同时这也是成本最低、最便捷的方式。 运行这样体量的帐号,好马应当配好鞍,不必要为这热点数据过度优化 为了少部分人的特殊需要,而支持可能极少数人才会用到的功能,我认为是不值得的 部分需要更高级特性的人,想必功底不会差,为何不自己 Fork 一份本地修改实现呢,反正都是开源作品 |
倘若目的是为了减小内存占用,我觉得可以对部分数据,即非热点数据进行本地磁盘持久化选项或提供自定义的高级方式 |
热点访问数据应当予以在内存中保留,以确保高可用、低风险、快响应 |
我并不觉得群成员列表属于热点数据。2022年2月3日 23:31,千橘 雫霞 ***@***.***>写道:
热点访问数据应当予以在内存中保留,以确保高可用、低风险、快响应
—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you commented.Message ID: ***@***.***>
|
事实上群成员列表在内部有相当多的隐性访问 |
这是我想到的一些可以优化的点:
如果要做这些优化,MiraiGo 肯定会有 break change(对 go-cqhttp 用户无感),可以考虑一次性更新上 并且 go-cqhttp 本身也可以使用 leveldb,对于群、好友数量较多的情况,内存占用会更小。对于群少的情况来说,可能几MB没什么区别,但是群多的情况,可能会存在几十MB的差距。 另外持久化可以让 go-cqhttp 启动速度更快,现在 400群 大概需要几十秒加载群列表。 |
隐性访问我觉得可以做成尽量 lazy 的,比如说 GroupMessage 可以去掉 Sender 结构体,只保留 from_uin,并且提供 |
很遗憾,lazy 并不 lazy 例,https://docs.go-cqhttp.org/event/#%E7%BE%A4%E6%B6%88%E6%81%AF 中, |
依赖 MiraiGo 的其他 golang 项目可以使用 lazy 的特性 https://github.com/Mrs4s/MiraiGo/network/dependents?package_id=UGFja2FnZS0yMjc0MTE4OTYx |
|
我支持持久化和提供Get、Set接口 |
有个问题,倘若你需要启动速度快,那么在加入了新群或群加入新成员而 gocqhttp 未同步完成前,收到了该群或该成员的消息,作何处理?丢弃? gocqhttp 不是 QQ 客户端,说白是转发消息,对时效性要求高,且一旦发出难以修改 我认为,未完全和服务器同步前,不具备接收消息的能力。等待所有必要数据加载完成后,有能力接收消息时再完成启动流程开始接收消息是符合逻辑的 |
如果是 lazy 获取 member,且开发者正好不需要使用 nick 字段,只用 group_code、from_uin 这些字段,实际上是可以在未同步前接受消息的。 |
gocqhttp:那我呢? 很遗憾,你很难假设开发者正好不需要使用。在大多数的框架里,往往包含有权限系统,其中需要有发送者的群权限信息,而这正好是需要你的 lazy 来获取 这样只会加大终端用户的理解负担,给调试带来不便,收益浅薄 |
可以在获取不到群,但是又急着使用的情况下,优先去获取需要使用的这个群的信息。(其他群可以慢点) 另外如果改成线程安全的 K-V 形式,可以避免因为多线程造成 group_list 中存在多个相同群的问题 https://github.com/Mrs4s/MiraiGo/blob/master/client/group_msg.go#L431 因为 GroupInfo 里面包含 members,如果同时保存了多份大群的 members,会占用非常多的内存(尤其是发口令红包的时候) |
请考虑在群较多,多个群并发量较大的情况下,集中请求获取群信息接口,是否易造成腾讯风控
依您所言,您可能更希望是实现自定义的或接管miraigo的逻辑,或是优化,而不是一开始所讨论的存储方式 |
现在的 MiraiGo 在启动之后就可以接受消息(刷新群列表之前),并发情况下会造成集中请求获取群信息接口。如果是 lazy 的,可以一定程度上避免你说的问题,不一定需要每次都获取群信息 https://github.com/Mrs4s/MiraiGo/blob/master/client/group_msg.go#L28 |
您说的不无道理,但我仍想提醒您,MiraiGo 是为 gocqhttp 设计的,这个功能对于 gocqhttp 而言,名存实亡。 转折: 倘若您能够说服 gocqhttp 用户,删去该字段,那么您提出的功能就有实际意义 上述内容假设于您将群成员列表数据存放至本地磁盘 |
对于您提出的 本身 MiraiGo 只提供低级 API,https://github.com/Mrs4s/go-cqhttp/blob/f8fa906a952dff1cb111c40411d1ae8632e83326/cmd/gocq/main.go#L341 中可见,gocqhttp 认为是等待群列表同步完成后再行注册事件接收回调 |
在刷新之前只是gocq不上报,但是MiraiGo收到message如果没有group_info,是会获取group_info的,并发情况下会造成多次获取相同群的信息,存到GroupList,可能会产生相同群的情况(这应该可以开另一个issue,和存储无关) |
通过接口,提供更优解, 个人建议实现后可以完善这部分文档 |
经过测试,1600好友+400群,占用内存85MB,可以考虑把 好友列表、群列表、群成员列表 放在磁盘
提供 interface 参数,允许自定义存储方式,使用磁盘、Redis等方式,保存 好友列表、群列表、群成员列表
The text was updated successfully, but these errors were encountered: