聊一聊关于聊天记录的存储

背景

即时通讯(Instant Messaging),也就是我们常说的 IM,其实在很多业务场景上都会有或多或少的应用,有的会是核心,有的会是辅助。

既然是聊天,那么必然就会产生聊天记录,而且聊天记录随着人数的增加和时间的推移,很容易出现爆炸式的增长,这个对存储其实压力是很大的。

举个大家都很熟悉的例子,一个群聊,几分钟不看,再打开就是 99+ 的未读消息。

把即时通讯这个技术,放到医疗环境下,也是同样适用的。

患者去线下医院看病,肯定离不开和医生的问答,这些问答,对系统来说,其实都是聊天记录。

如果把这个场景放到线上进行,也就是正常的和我们在微信聊天那样了。

说了那么多有的没的,也算是把大背景交代了一下,那么接下来就看看这个聊天记录存储的选型吧。

技术选型

既然要存储,那么肯定就会有很多选择,关系型数据库,非关系型数据库等。

当然这个很大程度上是和具体业务场景挂钩的,离开了业务场景,基本就是在空谈。

在医患关系里面的聊天记录,是一个十分十分核心的内容,并且必须要长期保存,不能丢,可查询。

并且这些聊天记录是和某次问诊强关联的,所以单独拿出几条聊天记录出来,是没有意义的,因为他们没有关联,串联不起来。

按照以往的经验看,一次问诊,医生和患者之间的聊天记录在 50 条之内的占据了大部分,超过50条的,占少数。

这个和其他的 IM 情景可能不太一样。

MySQL

业务开始,大概率就是选用 MySQL 去存了这些数据了,单库单表,但是这种情况下很容易达到单表千万和上亿的级别。

后面面临的基本就是分库分表的操作了。

分库分表,基本就是根据问诊号去进行哈希,然后放到不同的库不同的表。

这里会有一个不确定因素,分多少个库和分多少张表?

分的多,囊中羞涩;分的少,再一次达到量级的时候又要重新分,大动干戈,这个时候最怕的就是动到了哈希的规则。

所以选 MySQL 的话,到了中后期确实还是会有一点力不从心。线性扩展对这一块还是非常重要的。

如果想改动小,避免分库分表,或许可以试试 TiDB,但是它要的配置,也不是中小企业所能接受的,80% 以上的概率会被 Pass 掉。

https://docs.pingcap.com/zh/tidb/stable/hardware-and-software-requirements

Cassandra

Cassandra 是一个分布式、无中心、弹性可扩展的 NoSQL 数据库,基于 Amazon Dynamo 的分布式设计和 Google Bigtable 的数据模型。

https://cassandra.apache.org/doc/latest/architecture/overview.html

为什么考虑选型 Cassandra 呢?对上面说的医患场景,严格上是属于写多读少的,查询基本只会基于问诊号去查询,这个是相对比较明确的。

Discord 在 2017 年的时候有一篇博客讲述了他们是怎么存储数十亿消息记录的 ,说的比较详细了。

https://blog.discord.com/how-discord-stores-billions-of-messages-7fa6ec7ee4c7

其实他们选数据库的诉求,也是符合大部分涉及 IM 这一块的。

老黄也是从这里受到了启发,认识了这个数据库。

经常拿来比较的话,应该是 HBase,一个在国内火,一个在国外受欢迎。

可以看看这个对比,了解一下两者的异同:https://www.scnsoft.com/blog/cassandra-vs-hbase

如果选择要用 Cassandra, 那么数据模型的设计,一定是所有环节中最为重要的一步,如果这一步没有做好的话,那后面基本上会是灾难级别,基本不能愉快的玩耍。

那么对医患关系里面的这个聊天模型其实比较简单。

CREATE TABLE IF NOT EXISTS messages(inq_id text,send_time bigint,sender_id text,sender_role tinyint,msg_type tinyint,msg_body text,PRIMARY KEY (inq_id, send_time)
) WITH CLUSTERING ORDER BY (send_time ASC)

对照正常的 IM 群聊, 这个问诊号 (inq_id) 就可以认为是一个群聊,一个频道。

为什么没有消息Id这样的字段呢?多来源,非自研,无实际意义。

下面再来看看如何在 C# 里面进行操作, 这里用的是 DataStax 提供的 CassandraCSharpDriver 客户端。

写入:

var cluster = Cassandra.Cluster.Builder().AddContactPoints("127.0.0.1").WithDefaultKeyspace("messaging").Build();var inqId = "xxxxxx";
var sendTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
var senderId = "xxxx";
var senderRole = 1;
var msgType = 1;
var msgBody = "zzzz";string INSERT_SQL = @" INSERT INTO messages(inq_id, send_time, sender_id, sender_role, msg_type, msg_body)
VALUES (?, ?, ?, ?, ?, ?) ";var session = cluster.Connect();var stmt = session.Prepare(INSERT_SQL).Bind(inqId, sendTime, senderId, senderRole, msgType, msgBody));session.Execute(stmt);

读取:

var cluster = Cassandra.Cluster.Builder().AddContactPoints("127.0.0.1").WithDefaultKeyspace("messaging").Build();var inqId = "xxxxxx";string GET_MSG_SQL = @" SELECT * FROM messages WHERE inq_id = ? ";var session = cluster.Connect();var stmt = session.Prepare(GET_MSG_SQL).Bind(inqId);var rowset = session.Execute(stmt);Console.WriteLine("患者\t\t\t\t\t医生");foreach (var row in rowset)
{// 解析从 cassandra 中返回的行var msg_body = row.GetValue<string>("msg_body");var sender_role = row.GetValue<sbyte>("sender_role");if (sender_role == 0){Console.WriteLine($"{msg_body}\t\t\t\t\t");}else{Console.WriteLine($"\t\t\t\t\t{msg_body}");}
}

写在最后

存储的选择其实还是有点门道的,根据不同的应用场景,找出比较适合当前场景的几个方案,再选择一个成本没这么高的。

Cassandra 对聊天记录这个场景的存储还是有一定优势的,可以应对高速的数据增长,而不用在业务代码层做过多的适配;部署相对简单,无特殊依赖,运维成本相对较低。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/300724.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

考勤机信息同步不到服务器,考勤机实时同步功能上线啦

一、考勤机管理重磅上线&#xff0c;告别手动处理打卡数据考勤机打卡仍然是当前企业主流的考勤方式&#xff0c;而考勤机打卡数据的核算也是HR最头痛的一点。HR每个月都要去电脑打开复杂难用的考勤机配套软件&#xff0c;导出并整理打卡数据&#xff0c;逐个统计员工的迟到、早…

ios gb2312转utf-8

2019独角兽企业重金招聘Python工程师标准>>> 靠&#xff0c;想写个爬虫功能&#xff0c;结果一直是乱码&#xff0c;终于找到了转码的方法了 (NSString *) gb2312toutf8:(NSData *) data{ NSStringEncoding enc CFStringConvertEncodingToNSStringEncoding(kCFStr…

数学特级教师:数学除了做题目,我还必须让他们看这些!

▲ 点击查看很多时候&#xff0c;我们把数学简单的归为算数&#xff0c;归为计算能力&#xff0c;但数学更多的是一种培养逻辑思维能力的方式。包括一元二次方程、或者向量&#xff0c;或者几何证明。而在我们传统的数学课上&#xff0c;更多的是通过做题来理解数学知识&…

烟袋斜街-后海,印象已模糊

上个周末和猪头&#xff0c;廖廖一起去的。大家都神往已久&#xff0c;但是从未去过&#xff0c;这次一并去了&#xff0c;了却心愿。我不在北京&#xff0c;神往但是不能前去自然可以理解&#xff0c;但是他们两个已经在北京生活了六年&#xff0c;向往了六年&#xff0c;路程…

为啥 .NET 自带的 JsonSerializer 无法序列化 Field ?

咨询区 Theyouthis&#xff1a;最近我将项目升级到 .NET Core 3 之后&#xff0c;我发现自带的 System.Text.Json.JsonSerializer 序列化器有一个奇葩的问题&#xff0c;它不支持对 类字段 的序列化。。。参考如下代码&#xff1a;namespace ConsoleApp6 {class Program{static…

Windows下MinGW编译vim7.4

学习了一段时间Vim&#xff0c;感觉有些功能真的很方便。因学习原因&#xff0c;工作平台更换到一台老式Xp电脑上&#xff0c;重新安装了Vim7.4。官网默认版本不支持等宽字体和GDI渲染&#xff0c;需要手工编译一个修改过的版本。 1、下载MinGW 直接从MinGW官网下载的是在线安装…

除了中国,原来还有这么多国家采用十二生肖的啊~| 今日最佳

世界只有3.14 % 的人关注了青少年数学之旅一、肥宅快乐水&#xff08;qiu&#xff1f;&#xff09;A岛-匿名版二、永远不轻言放弃知识冷知识青年 图片五目马丁饭三、终于知道怎么倒立问了冷知识日报社四、千万不能浪费文医疗音乐手绘君五、世界上所有采用十二生肖的国家冷知识日…

命中率_数据说话!詹姆斯的“皇家射手团”命中率为近十年最低

北京时间10月13日&#xff0c;湖人球员丹尼格林更新个人社交媒体&#xff0c;发布自己与奥布莱恩杯的合影等&#xff0c;并配文“随你怎么说&#xff0c;我又多了一样你拿不走的东西”。格林晒出自己与杜德利、詹姆斯的合影。此前&#xff0c;格林因为在NBA总决赛G5中未能命中极…

.net core 微服务下的手工签名实现,以及消除中文乱码

最近在实现一款业主签字的需求&#xff0c;签字前端由vue下的某个共享组件实现&#xff0c;其采用Canvas绘图方式实现签名图片的生成&#xff0c;后台主要提供签名前文档的呈现&#xff0c;以及签名后文件合成过的签名文档保存。FastReport报表生成器FastReport .NET是适用于.N…

高性能通道

高性能通道 http://detail.1688.com/offer/896868540.html https://www.datastoragecables.com/qsfp/qsfp-qsfp/qsfp-qsfp-ib/C9494-M-IB.html【infiniband】 http://pkg-ofed.alioth.debian.org/howto/infiniband-howto.html#toc6【infiniband-ib】posted on 2013-10-28 21:26…

清华学霸直博简历火了!CPU、操作系统、编译器全自主写,刘知远点赞

全世界只有3.14 % 的人关注了青少年数学之旅清华大学直博面试的一则简历上了知乎热榜&#xff1a;“实现了在自己写的CPU上运行自己写的操作系统&#xff0c;以及自己实现的编译器生成的程序”。简历主人是清华计算机系本科生周聿浩同学&#xff0c;他顺利拿到直博名额&#xf…

使用Blazor开发内部后台(一):认识Blazor

转载技术社区中一位朋友最新的文章&#xff0c;介绍自己为公司的 WebForm 遗留系统使用 Blazor 重写前端 UI 的经历。前言啊&#xff0c;又好久没写文章了&#xff0c;这一年一直在接触新的领域&#xff0c;扩展了一下技术面&#xff0c;学了很多新东西。前阵子发现公司内部有个…

全球科技界最鼓舞人心领袖揭晓!马斯克第一,马云第五

全世界只有3.14 % 的人关注了青少年数学之旅谁是科技界最鼓舞人心的领袖&#xff1f;最近技术招聘网站Hired对3600多名技术人员进行了调查&#xff0c;最终马斯克击败贝佐斯、纳德拉、扎克伯格等人成功当选&#xff0c;马云排名第五。SpaceX被评为全球私人公司中第二大最受欢迎…

设置mysql表myisam_mysql myisam 优化设置设置

mysql myisam 优化设置设置更新时间&#xff1a;2010年03月16日 21:28:24 作者&#xff1a;mysql myisam 优化设置设置&#xff0c;需要的朋友可以参考下。myisam_max_[extra]_sort_file_size足够大delay_key_write减少io,提高写入性能bulk_insert_buffer_sizeconcurrent_ins…

NET问答: 为什么 String.IndexOf 在 .net5 和 netcore3 中返回值不一样?

咨询区 Farhad Zamani&#xff1a;当我在 .NET Core 3.1 中运行下面代码的时候&#xff0c;程序会返回 6。class Program{static void Main(string[] args){// .NET Core 3.1string s "Hello\r\nworld!";int idx s.IndexOf("\n");Console.WriteLine(idx)…

vSpere虚拟网卡介绍

在一个物理网络拓扑中&#xff0c;通常都是路由器-交换机-PC机的连接&#xff0c;不同的服务器和PC机&#xff0c;通过交换机的连接而相互连通。在VMwarevSphere架构下服务器会虚拟出交换机来供ESXHost虚拟机来使用&#xff0c;虚拟交换机有两种&#xff0c;vSwitch虚拟交换机和…

快速掌握MATLAB应用,只要从这一步开始!

有人说&#xff0c;“MATLAB除了不会生孩子&#xff0c;什么都会。”矩阵运算、数据可视化、GUI&#xff08;用户界面&#xff09;设计、甚至是连接其他编程语言&#xff0c;MATLAB都能轻松实现&#xff01;那么&#xff0c;MATLAB到底有多厉害&#xff1f;MATLAB拥有丰富的算法…

如何查看 .NET Core 3.1 源代码

背景在 .NET 走向开源后&#xff0c;我们可以方便的查看 .NET 内部的实现方式&#xff0c;学习和寻找问题&#xff0c;甚至参与到 .NET 的开发中。前段时间&#xff0c;同事需要查看 C# 的 Task 类 (System.Threading.Tasks) 的一些实现和内部的原理&#xff0c;想找 Task 类的…

装×失败的后果。。。 | 今日最佳

世界只有3.14 % 的人关注了青少年数学之旅传说中的“虎口夺食”摄像头留下了垃圾桶欺负我的证据用力过猛扯淡还是扯底裤装失败二进洗脚盆玻璃太干净了&#xff0c;注意左边这个傻子哎呀&#xff0c;这个傻子真的是傻中奖的感觉还是要量力而行滑的还真溜。。。电动车此刻注入了灵…

.net core 下的HttpClient、WebClient性能测试

有许多服务需要拉取api接口数据&#xff0c;因此后端开发少不了对Http访问请求进行封装&#xff0c;最主要的应用方式莫过于采用WebClient进行封装&#xff0c;简单易用&#xff1b;而.net core微软官方推荐的是HttpClient和HttpClientFactory&#xff0c;到底哪个性能更加强劲…