如何使用 Azure Table 存储进行大量查找
How to use Azure Table Storage for huge lookups
我有一个包含 2 GB 哈希值的存储,我想用 public Api.
检查一下
用例
假设我想创建一个 API 来检查我的产品是否认识某个人。
为了尊重个人隐私,我不想上传他的姓名、会员ID 等。
所以我决定 只上传一个哈希值 组合信息的哈希值,这将识别他。
现在我有 2 GB (6*10^7) 的 SHA256 哈希值,想以 疯狂 快速方式检查它们。
此 API 应托管在 Azure 中。
阅读 Azure 存储帐户的文档后,我认为 Azure Table 存储是正确的存储解决方案。
我会将 base64 哈希设置为分区键 并将 行键留空 .
问题
- 首先,Azure Table 是否适合这项工作?
- 这两者之间的表现是否不同:
- 分区键:base64 哈希,行键:空
- 分区键:'Upload Id',行键:empbase64 哈希
- 访问槽键的时间是否取决于table的大小?
检查分区键是否存在的最快方法是什么?
我认为我天真的第一次尝试并不是最好的方法。
if(members.Where(x=>x.PartitionKey == Convert.ToBase64String(data.Hash)).AsEnumerable().Any())
{
return req.CreateResponse(HttpStatusCode.OK, "Found Hash");
}别的
{
return req.CreateResponse(HttpStatusCode.NotFound, "Don't found Hash");
}
如何上传2GB的哈希值?
我考虑上传一个大文件并使用 azure 函数在每 256 位之后进行拆分并将值添加到 azure 存储中。或者有更好的主意吗?
我对此的看法:
如果您唯一需要的查询是 "check if existing hash exists"(并在需要时检索其详细信息),那么 Table 存储是完美的选择。密钥查找快速且便宜,2 GB 不算什么。
Hash 提供了最多的多样性,所以我会用它作为分区键。行键可以是任何东西。如果 Upload Id
从未用于(范围)查找,则不要将其用于键。
使用适当的分区键,查找时间应该是恒定的。
如果你的意思是你需要检查用户哈希是否存在,只需通过分区键+行键检索一行。这是最快的操作。参见 "Retrieve a single entity" here。
Table 存储支持批量插入。同样,2GB 并不多,您问这个问题所花的时间可能比上传所花的时间还多:)
我看到这是用 Azure-Functions 标记的,所以我要补充一点,Azure-Functions 让您可以直接绑定到 table 存储。参见 https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-storage-table
您甚至可以直接绑定到特定实体。
function.json 看起来像:
{
"name": "<Name of input parameter in function signature>",
"type": "table",
"direction": "in",
"tableName": "<Name of Storage table>",
"partitionKey": "<PartitionKey of table entity to read - see below>",
"rowKey": "<RowKey of table entity to read - see below>",
}
我有一个包含 2 GB 哈希值的存储,我想用 public Api.
检查一下用例
假设我想创建一个 API 来检查我的产品是否认识某个人。 为了尊重个人隐私,我不想上传他的姓名、会员ID 等。 所以我决定 只上传一个哈希值 组合信息的哈希值,这将识别他。 现在我有 2 GB (6*10^7) 的 SHA256 哈希值,想以 疯狂 快速方式检查它们。
此 API 应托管在 Azure 中。
阅读 Azure 存储帐户的文档后,我认为 Azure Table 存储是正确的存储解决方案。 我会将 base64 哈希设置为分区键 并将 行键留空 .
问题
- 首先,Azure Table 是否适合这项工作?
- 这两者之间的表现是否不同:
- 分区键:base64 哈希,行键:空
- 分区键:'Upload Id',行键:empbase64 哈希
- 访问槽键的时间是否取决于table的大小?
检查分区键是否存在的最快方法是什么? 我认为我天真的第一次尝试并不是最好的方法。
if(members.Where(x=>x.PartitionKey == Convert.ToBase64String(data.Hash)).AsEnumerable().Any()) { return req.CreateResponse(HttpStatusCode.OK, "Found Hash"); }别的 { return req.CreateResponse(HttpStatusCode.NotFound, "Don't found Hash"); }
如何上传2GB的哈希值? 我考虑上传一个大文件并使用 azure 函数在每 256 位之后进行拆分并将值添加到 azure 存储中。或者有更好的主意吗?
我对此的看法:
如果您唯一需要的查询是 "check if existing hash exists"(并在需要时检索其详细信息),那么 Table 存储是完美的选择。密钥查找快速且便宜,2 GB 不算什么。
Hash 提供了最多的多样性,所以我会用它作为分区键。行键可以是任何东西。如果
Upload Id
从未用于(范围)查找,则不要将其用于键。使用适当的分区键,查找时间应该是恒定的。
如果你的意思是你需要检查用户哈希是否存在,只需通过分区键+行键检索一行。这是最快的操作。参见 "Retrieve a single entity" here。
Table 存储支持批量插入。同样,2GB 并不多,您问这个问题所花的时间可能比上传所花的时间还多:)
我看到这是用 Azure-Functions 标记的,所以我要补充一点,Azure-Functions 让您可以直接绑定到 table 存储。参见 https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-storage-table
您甚至可以直接绑定到特定实体。 function.json 看起来像:
{
"name": "<Name of input parameter in function signature>",
"type": "table",
"direction": "in",
"tableName": "<Name of Storage table>",
"partitionKey": "<PartitionKey of table entity to read - see below>",
"rowKey": "<RowKey of table entity to read - see below>",
}