Redis 选择hash还是string 存储数据?

在stackoverflow 看到一个问题,Redis strings vs Redis hashes to represent JSON: efficiency?内容如下: I want to store a JSON payload into redis. There’s really 2 ways I can do this: One using a simple string keys and values. key:user, value:payload (the entire JSON blob which can be 100-200 KB) SET user:1 payload Using hashes HSET user:1 username “someone” HSET user:1 location “NY” HSET user:1 bio “STRING WITH OVER 100 lines” Keep in mind that if I use a hash, the value length isn’t predictable. They’re not all short such as the bio example above. Which is more memory efficient? Using string keys and values, or using a hash? ...

2019-06-22 · 3 min · 457 words

DynamoDB 最佳实践

面向DynamoDB的NoSQL设计 关系数据库设计和NoSQL之间的差异 关系型数据库可以灵活的查询数据,但是成本较高,高流量无法扩展 RDBMS 设计灵活,可以随时修改 NoSQL查询方式有限 需要对架构进行专门设计,以尽可能的加快查询速度。数据结构和需求高度相关,需要特制。 NoSQL设计的两个关键概念 需要先了解业务问题和应用程序的使用案例,然后再开始设计 应保留尽可能少的表。 了解NoSQL设计 三个基本属性 数据大小 了解一次存储和请求的数据量将有助于确定对数据进行分区的最有效方法。 数据形状 NoSQL 数据库不会在处理查询时重塑数据(如 RDBMS 系统所做的一样),而是整理数据以便数据在数据库中的形状与查询内容对应。这是加快速度并增强可扩展性的一个关键因素 数据速度 DynamoDB 通过增加可用于处理查询的物理分区的数量并通过跨这些分区有效分发数据来进行扩展。预先了解峰值查询负载可能有助于确定数据分区方式,从而最高效地使用 I/O 容量。 性能的一般准则 将相关数据放在一起 将相关数据集中放置到一个位置。将相关数据保留在最近位置会对成本和性能产生重大影响。 不是跨多个表分发相关数据项目,而是在 NoSQL 系统中尽可能紧密地保留相关项目。 作为一般规则,应在 DynamoDB 应用程序中保留尽可能少的表。 只需要一个表, 例外是涉及大量时间序列数据的情况或具有明显不同的访问模式的数据集 — 但这些都是例外。具有反向索引的单个表通常可启用简单查询来创建和检索应用程序所需的复杂层次数据结构。 使用排序顺序 可将相关项目组织起来并进行有效查询,前提是它们的键设计可促使它们一起排序 分发查询 您应该设计数据键以跨尽可能多的分区均匀分发流量,从而避免“热点”。 使用全局二级索引 通过创建特定的全局二级索引,可启用主表支持的查询以外的查询 设计并高效使用分区键的最佳实践 项目主键可以是仅分区键 也可以是分区键+排序键 高效使用突增容量 DynamoDB 当前可将未使用的读取和写入容量保留最多五分钟 (300 秒) 当读取或写入突增导致容量不足时使用。 DynamoDB适应性容量 DynamoDB 适应性容量 允许您的应用程序继续不受限地对热分区进行读写操作,前提是流量未超出表的配置的总容量或分区最大容量。自适应容量的工作原理是,自动增加分区的吞吐量容量来接收更多流量 示例表配置了 400 个写入容量单位 (WCU),这些容量单位均匀分布在 4 个分区中,每个分区每秒可以接收最多 100 个 WCU。分区 1、2 和 3 每秒接收的写入流量为 50 个 WCU。分区 4 每秒接收 150 个 WCU。此热分区可以在接受写入流量的同时仍具有未利用的突增容量,但是,它最终会限制每秒超过 100 个 WCU 的流量。 ...

2019-06-10 · 3 min · 538 words

redis 学习笔记

这篇 redis 学习笔记主要介绍 redis 的数据结构和数据类型,并讨论数据结构的选择以及应用场景的优化。 redis 是什么 Redis是一种面向“键/值”对类型数据的分布式NoSQL数据库系统,特点是高性能,持久存储,适应高并发的应用场景。 Redis 数据结构 动态字符串 (Sds) 双端列表 (LINKEDLIST) 字典 跳跃表 (SKIPLIST) 整数集合 (INTSET) 压缩列表 (ZIPLIST) HUGOMORE42 动态字符串 Sds (Simple Dynamic String,简单动态字符串)是 Redis 底层所使用的字符串表示,它被用 在几乎所有的 Redis 模块中 Redis 是一个键值对数据库(key-value DB),数据库的值可以是字符串、集合、列表等多种类 型的对象,而数据库的键则总是字符串对象 在 Redis 中, 一个字符串对象除了可以保存字符串值之外,还可以保存 long 类型的值当字符串对象保存的是字符串时,它包含的才是 sds 值,否则的话,它就 是一个 long 类型的值 动态字符串主要有两个作用: 实现字符串对象(StringObject) 在 Redis 程序内部用作 char * 类型的替代品 [双端列表] (http://origin.redisbook.com/internal-datastruct/adlist.html) 双端链表还是 Redis 列表类型的底层实现之一,当对列表类型的键进行操作——比如执行 RPUSH 、LPOP 或 LLEN 等命令时,程序在底层操作的可能就是双端链表 双端链表主要有两个作用: 作为 Redis 列表类型的底层实现之一; 作为通用数据结构,被其他功能模块所使用; 字典 字典(dictionary),又名映射(map)或关联数组(associative array), 它是一种抽象数据结 构,由一集键值对(key-value pairs)组成,各个键值对的键各不相同,程序可以将新的键值对 添加到字典中,或者基于键进行查找、更新或删除等操作 ...

2017-09-17 · 3 min · 543 words

Amazon DynamoDB 入门8:删除项目

上一篇介绍了DynamoDB 的更新,这一篇将会介绍项目删除操作和dynamoab-py 从表中删除数据 在 SQL 中,DELETE 语句从表中删除一个或多个行。DynamoDB 使用 DeleteItem 操作一次删除一个项目。 SQL 在 SQL 中,可使用 DELETE 语句删除一个或多个行。WHERE 子句确定要修改的行。示例如下: HUGOMORE42 DELETE FROM Music WHERE Artist = ‘The Acme Band’ AND SongTitle = ‘Look Out, World’; 我们可以修改 WHERE 子句以删除多个行。例如,删除某个特殊艺术家的所有歌曲,如下所示: DELETE FROM Music WHERE Artist = ‘The Acme Band’ Note 如果省略 WHERE 子句,则数据库会尝试从表中删除所有行。 DynamoDB 在 DynamoDB 中,可使用 DeleteItem 操作修改单个项目。 (http://docs.aws.amazon.com/zh_cn/amazondynamodb/latest/APIReference/API_DeleteItem.html?shortFooter=true)[API 语法如下]: { "ConditionExpression": "string", "ExpressionAttributeNames": { "string" : "string" }, "ExpressionAttributeValues": { "string" : { "B": blob, "BOOL": boolean, "BS": [ blob ], "L": [ "AttributeValue" ], "M": { "string" : "AttributeValue" }, "N": "string", "NS": [ "string" ], "NULL": boolean, "S": "string", "SS": [ "string" ] } }, "Key": { "string" : { "B": blob, "BOOL": boolean, "BS": [ blob ], "L": [ "AttributeValue" ], "M": { "string" : "AttributeValue" }, "N": "string", "NS": [ "string" ], "NULL": boolean, "S": "string", "SS": [ "string" ] } }, "ReturnConsumedCapacity": "string", "ReturnItemCollectionMetrics": "string", "ReturnValues": "string", "TableName": "string" } 参数说明: ...

2017-03-03 · 3 min · 435 words

Amazon DynamoDB 入门7:项目更新

上一节介绍了DynamoDB 的查询,本来计划这一节介绍使用索引的查询,不过随机看到了更新操作,就先写更新操作吧 update (修改表中的数据) SQL 语言提供用于修改数据的 UPDATE 语句。DynamoDB 使用 UpdateItem 操作完成类似的任务。 SQL 在 SQL 中,可使用 UPDATE 语句修改一个或多个行。SET 子句为一个或多个列指定新值,WHERE 子句确定修改的行。示例如下: UPDATE Music SET RecordLabel = 'Global Records' WHERE Artist = 'No One You Know' AND SongTitle = 'Call Me Today'; HUGOMORE42 如果任何行均不匹配 WHERE 子句,则 UPDATE 语句不起作用。 DynamoDB 在 DynamoDB 中,可使用 UpdateItem 操作修改单个项目。 API 语法如下: { "AttributeUpdates": { "string" : { "Action": "string", "Value": { "B": blob, "BOOL": boolean, "BS": [ blob ], "L": [ "AttributeValue" ], "M": { "string" : "AttributeValue" }, "N": "string", "NS": [ "string" ], "NULL": boolean, "S": "string", "SS": [ "string" ] } } }, "ConditionalOperator": "string", "ConditionExpression": "string", "Expected": { "string" : { "AttributeValueList": [ { "B": blob, "BOOL": boolean, "BS": [ blob ], "L": [ "AttributeValue" ], "M": { "string" : "AttributeValue" }, "N": "string", "NS": [ "string" ], "NULL": boolean, "S": "string", "SS": [ "string" ] } ], "ComparisonOperator": "string", "Exists": boolean, "Value": { "B": blob, "BOOL": boolean, "BS": [ blob ], "L": [ "AttributeValue" ], "M": { "string" : "AttributeValue" }, "N": "string", "NS": [ "string" ], "NULL": boolean, "S": "string", "SS": [ "string" ] } } }, "ExpressionAttributeNames": { "string" : "string" }, "ExpressionAttributeValues": { "string" : { "B": blob, "BOOL": boolean, "BS": [ blob ], "L": [ "AttributeValue" ], "M": { "string" : "AttributeValue" }, "N": "string", "NS": [ "string" ], "NULL": boolean, "S": "string", "SS": [ "string" ] } }, "Key": { "string" : { "B": blob, "BOOL": boolean, "BS": [ blob ], "L": [ "AttributeValue" ], "M": { "string" : "AttributeValue" }, "N": "string", "NS": [ "string" ], "NULL": boolean, "S": "string", "SS": [ "string" ] } }, "ReturnConsumedCapacity": "string", "ReturnItemCollectionMetrics": "string", "ReturnValues": "string", "TableName": "string", "UpdateExpression": "string" } 参数说明: ...

2017-02-07 · 4 min · 816 words

Amazon DynamoDB 入门6:query 和 scan

上一节我们介绍了DynamoDB索引的创建及管理,这一节我们将介绍query(查询)和scan(扫描)的使用。 查询Query SQL 可使用 SELECT 语句查询关键列、非关键列或任意组合。WHERE 子句确定返回的行。 DynamoDB Query 操作提供对存储数据的物理位置的快速高效访问。 可以将 Query 用于任何具有复合主键(分区键和排序键)的表。这里的表必须指定分区键的相等条件,并且可以选择性为排序键提供另一个条件。 KeyConditionExpression 参数指定要查询的键值。 HUGOMORE42 可使用可选 FilterExpression 在结果中的找出某些符号条件的项目。 在 DynamoDB 中,必须使用 ExpressionAttributeValues 作为表达式参数(例如,KeyConditionExpression和 FilterExpression)中的占位符。这类似于在关系数据库中使用绑定变量,在运行时将实际值代入 SELECT语句。 下边是query的语法: response = table.query( IndexName='string', Select='ALL_ATTRIBUTES'|'ALL_PROJECTED_ATTRIBUTES'|'SPECIFIC_ATTRIBUTES'|'COUNT', AttributesToGet=[ 'string', ], Limit=123, ConsistentRead=True|False, ConditionalOperator='AND'|'OR', ScanIndexForward=True|False, ExclusiveStartKey={ 'string': 'string'|123|Binary(b'bytes')|True|None|set(['string'])|set([123])|set([Binary(b'bytes')])|[]|{} }, ReturnConsumedCapacity='INDEXES'|'TOTAL'|'NONE', ProjectionExpression='string', FilterExpression=Attr('myattribute').eq('myvalue'), KeyConditionExpression=Key('mykey').eq('myvalue'), ExpressionAttributeNames={ 'string': 'string' }, ExpressionAttributeValues={ 'string': 'string'|123|Binary(b'bytes')|True|None|set(['string'])|set([123])|set([Binary(b'bytes')])|[]|{} } ) 参数说明: ...

2017-01-31 · 4 min · 766 words

Amazon DynamoDB 入门5:索引创建及管理

上一节我们介绍了项目的添加、修改、获取、删除(CRUD)操作,这一节将介绍索引的创建及管理。 创建索引 SQL 在关系数据库中,索引是一个数据结构,可对表中的不同的列执行快速查询。可以使用 CREATE INDEX SQL 语句将索引添加到现有表,并指定要建立索引的列。在创建索引后,可以照常查询表中的数据,但现在数据库可使用索引快速查找表中的指定行,而不是扫描整个表。 在创建一个索引后,数据库将自动维护此索引。只要修改表中的数据,就会自动更改索引以反映表中的更改。 HUGOMORE42 在 MySQL 中,您可以创建如下所示的索引: CREATE INDEX GenreAndPriceIndex ON Music (genre, price); DynamoDB 在 DynamoDB 中,我们可以创建和使用secondary index来实现类似目的。 DynamoDB 中的索引与其关系对应项不同。当我们创建secondary index时,必须指定其键属性 - 分区键和排序键。 在创建secondary index后,我们可以对它执行 Query 或 Scan 操作,就如同对表执行这些操作一样。 DynamoDB 没有查询优化程序,因此,仅在我们对secondary index执行 Query 或 Scan 操作时使用它。 DynamoDB 支持两种不同的索引: 全局二级索引 - 索引的主键可以是其表中的任意两个属性(可以在创建表时创建,也可以向现有表添加新全局二级索引,或者删除现有的全局二级索引)。 本地二级索引 - 索引的分区键必须与其表的分区键相同。不过,排序键可以是任何其他属性(是在创建表的同时创建的。不能向现有表添加本地二级索引,也不能删除已存在的任何本地二级索引)。 DynamoDB 确保secondary index中的数据最终与其表保持一致。我们可以请求对表或local secondary index执行强一致性 Query 或 Scan 操作。但是,全局二级索引仅支持最终一致性。 可使用 UpdateTable 操作并指定 GlobalSecondaryIndexUpdates 来将global secondary index添加到现有表: { TableName: "Music", AttributeDefinitions:[ {AttributeName: "Genre", AttributeType: "S"}, {AttributeName: "Price", AttributeType: "N"} ], GlobalSecondaryIndexUpdates: [ { Create: { IndexName: "GenreAndPriceIndex", KeySchema: [ {AttributeName: "Genre", KeyType: "HASH"}, //Partition key {AttributeName: "Price", KeyType: "RANGE"}, //Sort key ], Projection: { "ProjectionType": "ALL" }, ProvisionedThroughput: { "ReadCapacityUnits": 1,"WriteCapacityUnits": 1 } } } ] } 添加索引时必须向 UpdateTable 提供以下参数: ...

2017-01-18 · 3 min · 520 words

Amazon DynamoDB 入门4:项目的基本操作(CRUD)

上一节我们介绍了DynamoDB 表的操作,这一节将介绍项目的添加 修改 获取 删除操作。 创建项目 Amazon DynamoDB 提供了 PutItem 和 BatchWriteItem 两种方式写入数据 添加单个项目 在 Amazon DynamoDB 中,使用 PutItem 操作向表添加项目: HUGOMORE42 { TableName: "Music", Item: { "Artist":"No One You Know", "SongTitle":"Call Me Today", "AlbumTitle":"Somewhat Famous", "Year": 2015, "Price": 2.14, "Genre": "Country", "Tags": { "Composers": [ "Smith", "Jones", "Davis" ], "LengthInSeconds": 214 } } } 此表的主键包含 Artist 和 SongTitle。您必须为这些属性指定值。 以下是要了解的有关此 PutItem 示例的几个关键事项: ...

2017-01-18 · 5 min · 991 words

Amazon DynamoDB 入门3: 表的基本操作

之前两篇文章介绍了DynamoDB如何在本地安装以及基本的工作原理和API,这一节主要介绍如何使用DynamoDB。 基本的DynamoDB 操作包括表操作、项目操作和索引管理。 首先是链接数据库。和关系型数据库不同,DynamoDB 是一项 Web 服务,与其进行的交互是无状态的。应用程序不需要维护持久性网络连接。相反,与 DynamoDB 的交互是通过 HTTP(S) 请求和响应进行的。 HUGOMORE42 执行某项操作的步骤为: 应用程序将 HTTP(S) 请求发送到 DynamoDB。该请求包含要执行的 DynamoDB 操作的名称和参数。DynamoDB 将立即执行请求。 DynamoDB 返回一个包含操作结果的 HTTP(S) 响应。如果出错,DynamoDB 将返回 HTTP 错误状态和消息。 大多数情况下,我们编写应用程序代码访问DynamoDB。同时还可以使用 AWS 管理控制台或 AWS Command Line Interface (AWS CLI) 向 DynamoDB 发送临时请求并查看结果。 剩下的就让我们用代码展示吧! 表操作 我们知道,关系模型需要一个明确定义的架构,其中,数据将标准化为表、列和行。此外,在表、列、索引和其他数据库元素之间定义所有关系。但 DynamoDB 不同,DynamoDB 没有架构。每个表必须具有一个用来唯一标识每个数据项目的主键,但对其他非键属性没有类似的约束。DynamoDB 可以管理结构化或半结构化的数据,包括 JSON 文档。 表是关系数据库和 DynamoDB 中的基本数据结构。关系数据库管理系统 (RDBMS) 要求在创建表时定义表的架构。相比之下,DynamoDB 表没有架构 - 与主键不同,我们在创建表时无需定义任何属性或数据类型。 新建表 DynamoDB 使用 CreateTable 操作创建表,并指定参数,请求语法如下所示: { "AttributeDefinitions": [ { "AttributeName": "string", "AttributeType": "string" } ], "GlobalSecondaryIndexes": [ { "IndexName": "string", "KeySchema": [ { "AttributeName": "string", "KeyType": "string" } ], "Projection": { "NonKeyAttributes": [ "string" ], "ProjectionType": "string" }, "ProvisionedThroughput": { "ReadCapacityUnits": number, "WriteCapacityUnits": number } } ], "KeySchema": [ { "AttributeName": "string", "KeyType": "string" } ], "LocalSecondaryIndexes": [ { "IndexName": "string", "KeySchema": [ { "AttributeName": "string", "KeyType": "string" } ], "Projection": { "NonKeyAttributes": [ "string" ], "ProjectionType": "string" } } ], "ProvisionedThroughput": { "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "StreamSpecification": { "StreamEnabled": boolean, "StreamViewType": "string" }, "TableName": "string" } 必须向 CreateTable 提供以下参数: ...

2017-01-14 · 3 min · 611 words

Amazon DynamoDB 入门2: 工作原理、API和数据类型介绍

本节主要介绍DynamoDB 基本概念、核心组件、数据结构、Api DynamoDB工作原理 DynamoDB 基本概念 DynamoDB 是 AWS 独有的完全托管的 NoSQL Database。它的思想来源于 Amazon 2007 年发表的一篇论文:Dynamo: Amazon’s Highly Available Key-value Store。在这篇论文里,Amazon 介绍了如何使用 Commodity Hardware 来打造高可用、高弹性的数据存储。想要理解 DynamoDB,首先要理解 Consistent Hashing。Consistent Hashing 的原理如下图所示: HUGOMORE42 它的概念是: 我有一个足够大的Keyspace(2的160次方,比较一下:IPv6是2的128次方),我们记作X。 然后将X放在一个环形的空间里划分成大小相等的Y个 Partition,依次循环排列(如图),每个 Partition 由一个Vnode(Riak的概念)管理, 当你有M个Database Server(Node),Y个Vnode再平均映射到M个Node上。 当数据要插入时,将其主键(Hash Key)映射到K中的一个地址(Addr),对应到某个Vnode,再进一步对应到某个Node,如果这个数据需要N个Replica,则将数据写入Addr(Vnode a),Addr + 1(Vnode b), …,Add + N(Vnode n)。 这里,M就是你的Shards,N是Replica。 以后添加新的Node时,映射发生变化,只需要把相应的变化了的Vnode迁移到新的Node上即可。在这种结构下,Sharding/Replica对程序员基本上是透明的。 DynamoDB 核心组件 基本 DynamoDB 组件包括:表、项目、属性 表 - 类似于其他数据库系统,DynamoDB将数据存储在表中。表是数据的集合。(类似于关系型数据库中的表) 项目 - 每个表包含多个项目。项目是一组属性,具有不同于所有其他项目的唯一标识。(类似于其他数据库系统中的行、记录或元组。) 属性 - 每个项目包含一个或多个属性。属性是基础的数据元素,无需进一步分解。(类似于其他数据库系统中的字段或列。) 下图是一个名为 People 的表,其中显示了一些示例项目和属性: 请注意有关 People 表的以下内容: ...

2017-01-09 · 4 min · 652 words