推荐用于存储应用程序日志的Cassandra架构

zazmityj  于 2023-01-25  发布在  Cassandra
关注(0)|答案(1)|浏览(185)

我的任务是使用Cassandra来提出一个存储应用程序日志的模式。我对Cassandra相当陌生,但从我到目前为止所阅读和学到的,它可能是我们用例的最佳方法。
我们的应用程序每天发送数千条短信(由3家本地服务提供商提供),我们希望每次发送短信时都能保留一个日志(用于每个月底的对账等目的)。我们打算存储以下信息:

id                  text,      // uuid
phone_number        text,      // recipient of the SMS
message             text,      // Message sent
status              boolean,   // if the SMS was sent or not
response            text,      // Request response
service_provider    text,      // e.g Twilio, Telnyx, Venmo etc
date                timestamp, // Time SMS is sent

我们希望随时查询以下报表:
1.发送短信总数
1.在给定时间段内(2个日期之间)发送的短信总数
1.特定服务提供商发送的SMS总数(也在给定时间段内)
1.发送到特定收件人电话号码的短信总数(也在给定时间段内)
1.发送失败或成功的SMS总数(也在给定时间段内)
我想出了下面的表(3),但我觉得我是过度工程或过度思考它?也许它可以做得更简单?我将感谢任何建议,让它有效地工作。

create table sms_logs_by_id
(
    id                  text,
    phone_number        text,
    message             text,
    status              boolean,
    response            text,
    provider            text,
    service_provider    text,
    date                timestamp,
    primary key (id, date)
) with clustering order by (date DESC);

create table sms_logs_by_service_provider
(
    id                  text,
    phone_number        text,
    message             text,
    status              boolean,
    response            text,
    provider            text,
    service_provider    text,
    date                timestamp,
    primary key (service_provider, date)
) with clustering order by (date DESC);

create table sms_logs_by_phone_number
(
    id                  text,
    phone_number        text,
    message             text,
    status              boolean,
    response            text,
    provider            text,
    service_provider    text,
    date                timestamp,
    primary key (phone_number, date)
) with clustering order by (date DESC);

create table sms_logs_by_status
(
    id                  text,
    phone_number        text,
    message             text,
    status              boolean,
    response            text,
    provider            text,
    service_provider    text,
    date                timestamp,
    primary key (status, date)
) with clustering order by (date DESC);

到目前为止,查询运行得很好。我不确定这是否是对数据建模的最佳方式。我将感谢任何关于如何改进此数据模型的建议。谢谢!

pes8fvy9

pes8fvy91#

我看到的唯一潜在问题是最后3个表(按状态、电话号码和提供商记录),随着时间的推移,分区会变得越来越大。重要的是要记住,Cassandra有一个每个分区20亿个单元格的数学限制(其中一个“单元格”==一个列值或键)。但是您希望对数据建模,以便不会接近该限制,因为你的table在那之前很久就开始变慢了
对于这三种情况,我建议采用“分组”方法:

sms_logs_by_service_provider
...
primary key (service_provider, date)

对于这个问题,我的另一个担忧是您正在跟踪3个服务提供商。因此,除了随着每个消息增长的分区之外,只有3个分区。因此,数据分布得不是很好。由于每天发送数千条消息,我认为您的“bucket”需要相当精确......可能以“天”为单位。也许您可以使用“week_bucket”,“但我将使用day作为示例:

id                  text,
provider            text,
service_provider    text,
day_bucket.         int,
date                timestamp,
PRIMARY KEY ((service_provider, day_bucket), date, id)

这样,您就可以为service_providerday的每个组合创建一个分区。这将为您提供大量的数据分布,而且您的分区不会超出一天中发生的活动。(好主意)但是添加了id作为“平局决胜”,以防两条消息具有完全相同的时间戳。

create table sms_logs_by_phone_number (
...
primary key (phone_number, date)

所以对于这一条,我会采取类似的方法。但我们谈论的是个人用户,我们可以使用更大的存储桶。根据谷歌的快速搜索,平均每个人每天发送85条短信,每年31,025条。按年存储可能没问题。

id                  text,
phone_number        text,
year_bucket         int,
date                timestamp,
PRIMARY KEY ((phone_number, year_bucket), date, id)

phone_number分区已经提供了一些良好的分布。在其中添加year_bucket将确保分区不会有无限制的增长。

create table sms_logs_by_status(
...
primary key (status, date)

按状态分类的日志会有一个类似于“provider”表的问题,因为你可能只有几个状态,所以数据分布会受到限制。对于这个,你可能也会想使用一个小的桶,比如按天分类。

id                  text,
status              text,
day_bucket.         int,
date                timestamp,
PRIMARY KEY ((status, day_bucket), date, id)

不幸的是,这些更改会使您的查询模式复杂化,但它们对于保存以后出现问题是必要的。

相关问题