DynamoDB

        本来想写写进程、线程、轻量级线程、goroutine还有协程(coroutine),为什么我把goroutine单独列出来是因为它不是协程,所有翻译成协程的都是偷用概念,把比线程轻量的都叫做协程。算了,先不纠结这个,今天想写写DynamoDB,记录下经历。

        就如官网描述到的,无限扩展,好吧,具体实现也不得而知,但这个无限扩展的前提是诸多限制。在确认DynamoDB是否适口你的项目使用的时候,记得多分析它的限制,否则迟早会成为项目的瓶颈,或者减缓业务的开发。

        首先,DynamoDB统计不友好,想统计它的东西?最好还是放弃这个念头,扫描一遍的代价大得不可思议。在用DynamoDB之前,先弄好你的日志系统。
        其次,它不是缓存,虽然是说SSD搞的,但是连这个东西(HTTPS)的代价不是普通缓存所会做的,就它内部查询性能来看,也是几十上百毫秒级别的。
        再次,不要以为这个东西很容易用,各种SDK各种坑,拿python boto为例子,两个版本的实现,各自残缺,有些功能SDK根本提供不了,你要做好写RESTful requests的准备。
        最后,你要是会看英文且真的想用DynamoDB就别继续往下看了,直接看官网文档各种详尽和指引,以下只是个人心得和坑的摘录。

        第一个坑是数据类型,嗯,不完全符合JSON,也就是说,这个要做点格式转换,前不久才出了List和Map的支持,叫文档类型,官方建议可以把JSON压缩成Binary,这...。一条项目(就是一条record,叫item)最大存储容量为400KB(只是英文文档这样写,中文文档还没更新,依然写着64K,这有点小,除此以外,中文文档残缺不全,不值一嗔),这个还可以。读/写流量限制预设(Provisioned Throughput)是一个最大的坑,以流量限定读写速率和容量。单个读单位可在1秒内读1次且4KB以内的内容,40KB就要10个读单位,同样地,单个写单位每秒可写入1次且1KB以内内容。
        第二个坑来了,就是这个读/写流量限制预设,全局二级索引是和主表分开预设流量计算。最坑在于,倘若你想写入主表,主表的预设流量是够的而全局二级索引预设流量不够,这样就会插不进,报错,这样使得全局二级索引和新建一张表无异,新建一张表还更灵活。预设流量的另一个坑是,你的hashkey(整个数据库以hashkey作为主键,不知道的请到官网中文版补习)必须hash得均匀才能得到预设流量的最大效用。比如说,你预设了1000个读(预设读容量超过10000还需要递表申请),amazon帮你自动分在20个区存放,那么你每个区只会获得50个读的流量,假如你现在急着要读某一类别的数据,并且这一类别的不小心集中在某一区域,不好意思,你的消费将乘以个几倍几十倍(amazon的服务本身就贵)。如果你要强一致性读(默认是不强一致性读的,不懂的自己脑补),那么将会消耗两倍于脏读的读单位。
        第三大坑是索引,上面说到的全局索引是一个坑,还有一种叫二级本地索引也是一个坑,它居然有一条单个hashkey索引内容不超过10G的规定,这个索引内容投影属性*(这个概念请看官网)。这就是说,当你索引加投影单个item有200个字节(200个字节真心不多吧,一个uuid随便都32byte了,当然,你可以选择压缩...),200字节的情况下,该hashkey最多可以包含的条目是5000万条,这个规定直接给人限死了,你不能拿单个hashkey来玩,更别做太多投影。此外,索引是不能添加修改删除的,只能跟随表创建时添加。虽然有10G这个限定,但我觉得它的RangeKey和本地二级索引还是比较独特的,可以解决很大一部分的需求。前提是,最深的索引就是二级,你要做三级四级的索引就要想一下办法了,这个想一下办法也可以再解决一大部分的需求吧。
        第四,别考虑太多事务啊原子操作之类,它做不了,简单的自增还是可以的。
        最后就是SDK,如果你只是简单的使用,python的SDK boto没什么大问题,但你考虑到并发冲突,部分属性修改兼上是否覆盖写入等等的问题的时候,boto压根就不能解决,这就需要又花费一大块精力去手工Restful了,当然,如果你想用上tonado,没有现成的异步模块可用。

        如果你已经跳过上述的坑,相信离DynamoDB符合你的项目需求已经不远了,当然,性能方面我还没做过多测试,准备上线亿级以上条目的项目了,详情敬请期待。


已标记关键词 清除标记
<div class="post-text" itemprop="text"> <p>I have populated a local DynamoDB instance with some values from this JSON</p> <pre><code>[ { "Id": 1, "Type": "fruit", "Name": "bananas", "Price": 0.25 }, { "Id": 2, "Type": "fruit", "Name": "apples", "Price": 0.50 }, { "Id": 3, "Type": "fruit", "Name": "avocados", "Price": 1.25 }, { "Id": 4, "Type": "vegetable", "Name": "carrots", "Price": 1.00 } ] </code></pre> <p>And want to read, say all the items in this database. I believe Querying the database can do this, but in for my query input code I have</p> <pre><code>func main() { type Product struct { Id int `json:"Id"` Type string `json:"Type"` Name string `json:"Name"` Price float64 `json:"Price"` } config := &aws.Config{ Region: aws.String("us-west-2"), Endpoint: aws.String("http://localhost:8000"), } sess := session.Must(session.NewSession(config)) svc := dynamodb.New(sess) input := &dynamodb.QueryInput{ TableName: aws.String("Products"), KeyConditions: map[string]*dynamodb.Condition{ "Id": { ComparisonOperator: aws.String("EQ"), AttributeValueList: []*dynamodb.AttributeValue{ { N: aws.String("1"), }, }, }, }, } result, err := svc.Query(input) if err != nil { fmt.Println(err.Error()) return } var products []Product err = dynamodbattribute.UnmarshalListOfMaps(result.Items, &products) // print the response data for _, m := range products { fmt.Printf("Product: '%s' (%f) ", m.Name, m.Price) } } </code></pre> <p>so far and it only outputs bananas as the since the query is trying to match id = 1 (Id is my hash primary key). </p> <p>I tried to modify the keycondition to something like this instead</p> <pre><code>"Id": { ComparisonOperator: aws.String("BETWEEN"), AttributeValueList: []*dynamodb.AttributeValue{ { N: aws.String("0"), }, { N: aws.String("5"), }, }, }, </code></pre> <p>in an attempt to read every item but it says "ValidationException: Query key condition not supported". Am I doing the query statement incorrectly? Or is there some better way of listing items in dynamoDB? (Like if I wanted to list everything with "Type" == "fruit" for example, then output the first 3 items in the database.</p> </div>
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页