存储和检索数百万个JSON编码的事件(PHP/数据库)

存储和检索数百万个JSON编码的事件(PHP/数据库),php,mysql,json,mongodb,amazon-dynamodb,Php,Mysql,Json,Mongodb,Amazon Dynamodb,假设我们有以下JSON事件数据示例: { "eventId":"eb1363c3-6bf7-4a42-9daa-66270b922367", "timestamp":"2014-10-28T09:12:22.628Z", "ip":"1.2.3.4", "device":{ "type":"mobile", "os":{ "name":"iOS", "version":"7.1.1"

假设我们有以下JSON事件数据示例:

{
    "eventId":"eb1363c3-6bf7-4a42-9daa-66270b922367",
    "timestamp":"2014-10-28T09:12:22.628Z",
    "ip":"1.2.3.4",
    "device":{
        "type":"mobile",
        "os":{
            "name":"iOS",
            "version":"7.1.1"
        },
        "name":"iPhone 4/4s",
        ...
    },
    "eventType":"AddedProductToCart",
    "store":"US",
    "product":{
        "sku":"ABC123",
        "name":"Yellow Socks",      
        "quantity":1,       
        "properties":{
            "foo":"bar",
            "bar":1
        }       
        ...
    },
    "user":{
        "id":123456,
        "name":"jeff",
        "type":"registered"
        ...
    }
}
虽然始终提供“eventId”和“timestamp”,但数组的结构可能会有所不同,并且不尽相同。大约有30-40种独特的事件类型,它们都具有不同的事件属性。大多数事件数据都具有嵌套结构

存储这些事件属性的最佳方法是什么?我研究了MongoDB、DynamoDB和一个名为EventStore()的项目。显然,我也考虑过MySQL,但我想知道它在我们的用例中会如何运行

数据的存储只是第一部分。在此之后,我们应该能够使用如下复杂查询来查询数据库/事件存储(例如,不仅仅是通过索引ID检索):

等等

我们预计每月约有1000万次活动。这相当于平均每秒3-4次写入,可能更像峰值/最坏情况下每秒30-40次写入。存储不应该是一个真正的问题-每个事件的总大小可能不会超过1或2kb(相当于每100万个事件1-2GB)

查询部分最好使用PHP。例如,DynamoDB有一个用于PHP的SDK,这肯定会促进我们的开发

我们最好的解决方案是什么?写入速度应该非常快,我们的查询也应该可以接受。简而言之,我们正在寻找一个低成本的数据存储,以便轻松存储和检索(->不仅使用索引查询,而且还使用嵌套JSON中的事件属性查询)我们的数据


谢谢您的建议,如果需要更多信息来正确回答这个问题,我很乐意提供更多信息。

MongoDB是一个不错的选择。它可以轻松地处理写操作(在我的笔记本电脑上,
mongod
可以看到更多操作)

您提到的查询是基本查询。例如:

select all events where eventType is "AddedProductToCart" and timestamp > 2 weeks ago
-> should return all "AddedProductToCart" from 2 weeks ago until now

select all events where device.OS.name is "iOS" and device.OS.version is "7.1.1"
-> should return all events from iOS 7.1.1
db.collection.find({"device.OS.name":"iOS","device.OS.version":"7.1.1"})
和(因可读性而缩短)

如果指数设置正确,这些指数应该是闪电般的快。您甚至可以使用TTL索引自动删除某个时间之前的事件

对于数据分析,您拥有map/reduce和MongoDB极其强大的聚合框架

让我们来谈谈缺点。虽然使用MongoDB进行扩展相对容易,但出于某种原因,人们认为具有自动数据分发功能的复制分片集群与MongoDB的其余部分一样容易管理。关键词是它相对容易(与MySQL或-Lord help us-Oracle的复制数据分区相比),但它仍然存在一些缺陷

在分片环境中进行时间点恢复而不使用MMS是可能的,但您确实需要知道自己在做什么,因为分片的各个备份的同步相当棘手


无论您选择哪个数据库,我强烈建议您与相应的专家联系。生产数据是基本的,没有数据库可以由非专业人员规划和维护。

MongoDB是一个很好的选择。它可以轻松地处理写操作(在我的笔记本电脑上,
mongod
可以看到更多操作)

您提到的查询是基本查询。例如:

select all events where eventType is "AddedProductToCart" and timestamp > 2 weeks ago
-> should return all "AddedProductToCart" from 2 weeks ago until now

select all events where device.OS.name is "iOS" and device.OS.version is "7.1.1"
-> should return all events from iOS 7.1.1
db.collection.find({"device.OS.name":"iOS","device.OS.version":"7.1.1"})
和(因可读性而缩短)

如果指数设置正确,这些指数应该是闪电般的快。您甚至可以使用TTL索引自动删除某个时间之前的事件

对于数据分析,您拥有map/reduce和MongoDB极其强大的聚合框架

让我们来谈谈缺点。虽然使用MongoDB进行扩展相对容易,但出于某种原因,人们认为具有自动数据分发功能的复制分片集群与MongoDB的其余部分一样容易管理。关键词是它相对容易(与MySQL或-Lord help us-Oracle的复制数据分区相比),但它仍然存在一些缺陷

在分片环境中进行时间点恢复而不使用MMS是可能的,但您确实需要知道自己在做什么,因为分片的各个备份的同步相当棘手


无论您选择哪个数据库,我强烈建议您与相应的专家联系。生产数据是基本的,没有数据库可以由非专业人员规划和维护。

MongoDB是一个很好的选择。它可以轻松地处理写操作(在我的笔记本电脑上,
mongod
可以看到更多操作)

您提到的查询是基本查询。例如:

select all events where eventType is "AddedProductToCart" and timestamp > 2 weeks ago
-> should return all "AddedProductToCart" from 2 weeks ago until now

select all events where device.OS.name is "iOS" and device.OS.version is "7.1.1"
-> should return all events from iOS 7.1.1
db.collection.find({"device.OS.name":"iOS","device.OS.version":"7.1.1"})
和(因可读性而缩短)

如果指数设置正确,这些指数应该是闪电般的快。您甚至可以使用TTL索引自动删除某个时间之前的事件

对于数据分析,您拥有map/reduce和MongoDB极其强大的聚合框架

让我们来谈谈缺点。虽然使用MongoDB进行扩展相对容易,但出于某种原因,人们认为具有自动数据分发功能的复制分片集群与MongoDB的其余部分一样容易管理。关键词是它相对容易(与MySQL或-Lord help us-Oracle的复制数据分区相比),但它仍然存在一些缺陷

在分片环境中进行时间点恢复而不使用MMS是可能的,但您确实需要知道自己在做什么,因为分片的各个备份的同步相当棘手


无论您选择哪个数据库,我强烈建议您与相应的专家联系。生产数据是基本的,没有数据库可以由非专业人员规划和维护。

MongoDB是一个很好的选择。它可以轻松地处理写操作(在我的笔记本电脑上,
mongod
可以看到更多操作)

您提到的查询是基本查询。例如:

select all events where eventType is "AddedProductToCart" and timestamp > 2 weeks ago
-> should return all "AddedProductToCart" from 2 weeks ago until now

select all events where device.OS.name is "iOS" and device.OS.version is "7.1.1"
-> should return all events from iOS 7.1.1
db.collection.find({"device.OS.name":"iOS","device.OS.version":"7.1.1"})
和(因可读性而缩短)

如果指数设置正确,这些指数应该是闪电般的快。您甚至可以使用TTL indice