我正在使用Azure表存储,并试图找出提高性能的最佳方法.我执行的查询非常简单 - 使用分区键和行键的精确选择,或者带有列表的where子句(例如,WHERE x == 1或x == 2或x == 3等).一旦我收回数据,我就不会在数据上下文中跟踪它(不需要更改跟踪等).同样保存数据,因此我只将其添加到上下文以启用保存.
目前,我正在使用.NET库(存储客户端).由于我不使用更改跟踪和TableServiceContext的其他功能,我正在考虑直接使用HTTP API.有没有人尝试过两种选择?如果是这样,你看到了什么样的性能差异?
谢谢,埃里克
是否可以使用Windows Azure表存储服务进行条件插入?
基本上,我想要做的是将新的行/实体插入到表存储服务的分区中,当且仅当我上次查看时该分区中没有任何更改.
如果您想知道,我会考虑事件采购,但我认为问题比这更普遍.
基本上我想阅读部分或整个分区,并根据数据内容做出决定.为了确保自加载数据后分区中没有任何更改,插入应该像普通的乐观并发一样:只有在分区中没有任何更改的情况下插入才会成功 - 没有添加,更新或删除任何行.
通常在REST服务中,我希望使用ETag来控制并发性,但据我所知,分区没有ETag.
我能想到的最好的解决方案是为表中的每个分区维护一个单行/实体,其中包含一个时间戳/ ETag,然后使所有插入包含一个由插入组成的批处理以及这个'的条件更新'时间戳实体'.然而,这听起来有点麻烦和脆弱.
Azure表存储服务可以实现吗?
etag azure optimistic-concurrency event-sourcing azure-table-storage
我无法使我的单元测试正常工作.它适用于我实际遇到Azure表存储的集成测试.我猜的问题是对属性QueryableEntities的模拟,它从mock中重新构造了一个Queryable,但它从ServiceContext类返回一个DataServiceQuery.是否可以创建一个返回Queryable的DataServiceQuery类型的存根?
这是我的代码:
测试
[TestMethod]
public void GetAExistingWordInStorageShouldReturnCorrectWord()
{
Word expected = new Word(Dictionaries.Swedish.ToString(), "Word", "Word");
List<Word> Words = new List<Word>();
Words.Add(new Word(Dictionaries.Swedish.ToString(), "Word", "Word"));
IQueryable<Word> WordQueryable = Words.AsQueryable<Word>();
var mock = new Mock<IServiceContext<Word>>();
mock.Setup(x => x.QueryableEntities).Returns(WordQueryable);
DictionaryRepository dr = new DictionaryRepository(Models.Dictionaries.Swedish, "testdictionaries");
dr.Context = mock.Object;
Word result = dr.GetWord(expected.Text, false);
Assert.AreEqual(expected, result);
}
Run Code Online (Sandbox Code Playgroud)
IServiceContect接口
public interface IServiceContext<TEntity>
{
IQueryable<TEntity> QueryableEntities {get;}
}
Run Code Online (Sandbox Code Playgroud)
ServiceContext类
public class ServiceContext<TEntity> : TableServiceContext, IServiceContext<TEntity> where TEntity : TableServiceEntity
{ …Run Code Online (Sandbox Code Playgroud) 我无法找到如何查看azure诊断日志.我写的代码如下.
DiagnosticMonitorConfiguration config = iagnosticMonitor.GetDefaultInitialConfiguration();
System.Diagnostics.Trace.Listeners.Add(new Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitorTraceListener());
config.Logs.ScheduledTransferLogLevelFilter = LogLevel.Information;
config.WindowsEventLog.ScheduledTransferPeriod = System.TimeSpan.FromMinutes(1.0);
DiagnosticMonitor.Start("Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString", config);
Run Code Online (Sandbox Code Playgroud)
然后我Trace.WriteLine("some message");在代码中添加了.现在我在哪里可以找到这些消息.我检查了Visual Studio服务器资源管理器,在那里我添加了我的存储帐户参考.wad-control-container只有配置文件.
我真的非常希望将URI存储为Azure表存储中的RowKey值.根据文档,RowKeys不能包含URI中常见的字符(/,\,#,?).
解决方案似乎很简单:只需编码URI即可.但这不起作用.无论出于何种原因,可以插入包含序列 %2f(正斜杠的编码值)的任何值,但不会查询,即使'%2f'不包含任何禁用字符.
好的,那么base64编码怎么样?不.它产生偶尔的正斜杠字符,这是不允许的.
那么有一种编码字符串(URI)的方法可以可靠地存储为Azure表中的RowKey吗?优选地,但不是必须地,人类可读的东西.
我想用一个简单的TableQuery从我的Azure表中获取前n行.但是使用下面的代码,无论我对Take的限制如何,都会获取所有行.
我究竟做错了什么?
int entryLimit = 5;
var table = GetFromHelperFunc();
TableQuery<MyEntity> query = new TableQuery<MyEntity>()
.Where(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, "MyPK"))
.Take(entryLimit);
List<FeedEntry> entryList = new List<FeedEntry>();
TableQuerySegment<FeedEntry> currentSegment = null;
while (currentSegment == null || currentSegment.ContinuationToken != null)
{
currentSegment = table.ExecuteQuerySegmented(query, this.EntryResolver, currentSegment != null ? currentSegment.ContinuationToken : null);
entryList.AddRange(currentSegment.Results);
}
Trace.WriteLine(entryList.Count) // <-- Why does this exceed my limit?
Run Code Online (Sandbox Code Playgroud) 我试图找到一个关于延续令牌和Azure存储库2.0问题的明确答案,因为2.0之前的版本(StorageClient)和当前版本(存储)之间似乎存在显着差异.
除了MSDN文档,它没有为我澄清上述问题,很难找到有关版本2.0及更高版本库的延续令牌的信息,因为早期版本的命名如此相似(CloudTableQuery vs TableQuery)搜索结果受到有关早期版本的信息的污染.
那么,是否在Microsoft.WindowsAzure.Storage客户端(存储库的2.0版)内部处理了持续令牌?我能相信我得到的结果集是完整的结果集吗?
谢谢!
我对Azure存储相对较新,并且已经实施了一段时间的解决方案.而且我一直遇到障碍,让我觉得我没有为我正在存储的数据应用正确的存储类型.
所以这更像是一个整体问题:
到目前为止,我一直在使用表存储,现在我正在为此付费.随着解决方案需求的增长,我发现自己无法根据需要访问数据.
例如,我需要获取表中的50个最新条目,但我不能在查询中使用OrderBy.我需要获取总条目数,但不能使用Count.
我一直认为,我计划在不知道确切的RowKey和PartitionKey的情况下定期访问的任何数据应该在Azure SQL中编入索引,并存储在表中.它是否正确?
我还发现自己将对象重新创建为Entity对象,但由于对数据类型的严格限制,我经常最终将对象序列化为字节数组.虽然表行最多可容纳1MB,但该行上的字节数组可能只能容纳64KB,此时我最终会使用Blob存储.
所以最后我觉得我最好只将所有数据放在Azure SQL中并索引更大的数据,但将其保存为blob.当然这感觉不太正确,因为这会使Table存储没有真正的目的.
所以我想知道是否有什么指导何时使用哪种存储.
在我的情况下,我在某些区域有大量数据,其中一些占用了相当大的空间(通常高于64KB),但我还需要非常频繁地访问数据,并且需要能够对其进行过滤和排序通过某些价值观.
我觉得我做得不对劲.我不明白的东西.我在这里错过了什么?
azure-storage azure-storage-blobs azure-table-storage azure-sql-database
我阅读了Azure Table/Blob/SQL存储之间的大量比较,我想我对所有这些都有很好的理解......但是,我仍然不确定在哪里可以满足我的特定需求.也许某人有类似情景的经验并能够提出建议.
是)我有的
一个SQL Azure数据库,用于在varchar(max)列中的原始HTML中存储文章.每行还有许多元数据列和许多索引,以便于查询.该表包含许多对用户,订阅,标签等的引用 - 因此我的项目将始终需要SQL DB.
有什么问题
我已经在这个表中有大约500,000篇文章,我预计它每年会增加数百万篇文章.每篇文章的HTML内容可以在几KB到1 MB之间,或者在极少数情况下,大于1 MB.
出现了两个问题:由于Azure SQL存储空间很昂贵,而且比以后更早,因此我将自己负责存储这个存储的成本.此外,我还会比以后更早地达到150 GB数据库大小限制.这500,000篇文章现在已占用1.6 GB的数据库空间.
我想要的是
很明显,那些HTML内容必须离开SQL DB.虽然文章表本身必须保留用于将其加入用户,订阅,标签等以便快速关联发现所需文章,但至少保存HTML内容的列可以外包到更便宜的存储.
乍一看,Azure Table存储看起来非常合适
非常便宜的价格和快速查询在一个大表中的数TB的数据 - 听起来很完美,有一个单独的表存储表将文章内容作为SQL DB的附加组件.
但是通过这里的比较显示它甚至可能不是一个选项:对于98%的文章,每列64 KB就足够了,但是对于某些单篇文章,即使整个1 MB的行限制也可能会留下2%还不够.
Blob存储听起来完全错误,但......
所以Azure上只有一个选项:Blob.现在,它可能没有听起来那么错误.在大多数情况下,我一次只需要一篇文章的内容.使用Blob存储时,这应该可以正常工作.
但我也有查询,我需要一次50行,100行甚至更多行,甚至包括内容.因此,我必须运行SQL查询来获取所需的文章,然后从Blob存储中提取每一篇文章.我对此没有任何经验,但我无法相信在执行此操作时我可以保持毫秒级的查询时间.对于我的项目而言,花费多秒的查询是绝对禁止的.
所以它似乎也不是一个合适的解决方案.
我看起来像个有计划的人吗?
至少我有类似计划的东西.我想过只将"适当的记录""导出"到SQL表存储和/或Blob存储中.
像"只要内容<64 KB将其导出到表存储,或者将其保存在SQL表中(甚至将此单个XL记录导出到BLOB存储中)"
这可能足够好了.但它使事情变得复杂,并且可能不容易出错.
那些其他选择
还有一些像MongoDB和CouchDB这样的其他NoSQL DB似乎更符合我的需求(至少从我天真的角度来看,那些刚读过纸上规格的人,我没有经验).但是他们需要自我托管,如果可能的话,有些事我想摆脱它.我在Azure上根据自托管服务器和服务的需要尽可能少地做.
你真的在这儿读过吗?
那么非常感谢你宝贵的时间和思考我的问题:)
任何建议将不胜感激.如你所见,我有自己的想法和计划,但没有什么能比以前走过路上的人有经验:)
谢谢,伯恩哈德
azure mongodb azure-storage-blobs azure-table-storage azure-sql-database
我多年来一直在使用 azure 表存储,但我不确定使用最新的 WindowsAzure.Storage 库版本 5.0.1-preview(用于新的 ASP.NET 5 应用):
问题: 给定一个分区键和行键,删除该行而不先检查是否存在,如果不存在则不会失败。
当前解决方案:此代码有效...但异常处理令人困惑:
public async Task DeleteRowAsync(CloudTable table, string partition, string row)
{
var entity = new DynamicTableEntity(partition, row);
entity.ETag = "*";
var op = TableOperation.Delete(entity);
try
{
await table.ExecuteAsync(op);
}
catch (Exception ex)
{
var result = RequestResult.TranslateFromExceptionMessage(ex.Message);
if (result == null || result.HttpStatusCode != 404)
throw ex;
}
}
Run Code Online (Sandbox Code Playgroud)
问题:
异常本身将我指向这个 TranslateFromExceptionMessage 方法......我找不到关于它和 WrappedStorageException (抛出的异常的类型)的大量信息。这是检查存储异常中的 404 错误的某种新的/首选方法吗?有谁知道现在是否所有存储异常都会使用它,或者我是否需要编写代码来测试和弄清楚?
有一个 StorageException 类型的 InnerException。大概我们使用 StorageException.RequestInformation.HttpStatusCode 的旧代码可以以相同的方式访问这个内部异常。那是“OK”,还是以某种方式更好或更健壮地解析这些新的 XML 错误消息?
对于这种情况,我应该考虑完全不同的方法吗?