我试着将Redis和ElastiCache简单总结一下,让人更易理解
首先
我最近才开始学习并总结了以前仅仅听说过的Redis。这是为了那些虽然听说过Redis但对其内部不熟悉的人,或是在项目中随意使用Redis却实际上并不了解的人而准备的页面。
非关系型数据库
首先从NoSQL开始,然后再考虑Redis。
背景
随着大数据的出现,传统的关系型数据库已经无法满足处理需求,因此出现了NoSQL。大数据的定义有很多种,但在这里我们将满足3V(Volume/Velocity/Variety)的数据称为大数据。
为了解决容量和速度的问题,需要使用NoSQL技术。
当与大量数据(Volume)和以秒为单位的大量数据(Velocity)相关的问题时,有两种处理方式:一种是扩展(Scale-up)(增加内存、增加核心数、实现SSD化),另一种是扩展(Scale-out)。
然而,扩展往往存在着物理限制,并且关系型数据库(RDB)的扩展通常较为困难。
与关系型数据库相比,NoSQL通常更容易实现扩展性。
为了解决Variety的问题,需要使用NoSQL。
在关系型数据库中处理非关系型的多样化数据本来就很困难。
特征
-
- 4つの種類と代表的なOSS
KVS(キーバリューストア): キーとバリューの組み合わせ
Redis
memcached
カラム指向データベース: 列方向のデータのまとまりをファイルシステム上の連続した位置に格納し効率的にアクセスする
cassandra
HBASE
ドキュメント指向データベース: キーに対してJSONあるいはXMLを格納する
mongoDB
couchDB
グラフ指向データベース: グラフ理論に基づいて関連性を持たせる
neo4j
TITAN
高速
インメモリで動作
トランザクション処理ができない
ACID特性でない
スケールしやすい
ただしAWSのAuroraのようにスケールが容易なRDBもでてきているためこの特徴は薄れてきている
在使用NoSQL和关系型数据库(RDB)时要适当选择
-
- サービスはビッグデータを扱う性能が求められるものか?データはNoSQLで扱えるものか?を自問自答する。YesならNoSQLを採用する。
どうしてもリレーショナルデータにできないデータなのか
トランザクション管理する必要の無いデータなのか
最悪揮発しても問題ないデータなのか
そうでなければRDBで管理する。RDBで管理できるものは極力RDBに寄せちゃう。
ここは個人によって考え方が違うと思う
不必要にNoSQLを採用するとシステムの複雑性がぐんと上がるので慎重に採用すること。
Redis是一种高性能的开源内存键值存储数据库系统。
终于轮到Redis了。
特点
-
- Remote Dictionary Serverの略
-
- OSS(BSDライセンス)
-
- KVS
-
- 豊富なデータ型
String/List/Set/Sorted Set/Hash
高速
インメモリDBだから
永続化設定可能
シングルスレッド
自動的に排他的となる
Redis3.0以降ならスケールアウト可能(2018/11時点ではRedis5.0.0が最新)
丰富的数据类型
-
- String
key(いわゆるkey)/value(いわゆるvalue)
key-valueのセットを複数持つイメージ
List
key(list名)/value(listに格納する値)
listの先頭か末尾にvalueを追加する
list自体を複数持つイメージ
Set
key(set名)/value(setに格納する値)
setなので重複を許さない
順不同
set自体を複数持つイメージ
Sorted Set(ZSet)
key(set名)/value(setに格納する値)
setなので重複を許さない
順番はscoreで保持する(setへの保存時にscroeを指定する)
sorted set自体を複数持つイメージ
Hash
key(hash名)/value(fieldとvalueを持つhash)
hash(map, dict)の入れ子構造になる
順不同
hash自体を複数持つイメージ
这篇文章就像图中的这部分一样容易理解。
复制提供的物品
通过将主节点的数据复制到从节点上来实现读取处理的负载均衡和容错性增强的方法。主节点可以进行读写操作,而从节点仅能进行读取操作。主节点可以有多个从节点。复制是异步进行的。设置方法可以参考本文。在后面提到的AWS ElastiCache服务中,将主节点称为”Primary Node”,将从节点称为”Read Replica”。
数据持久化(备份)
AWS的ElastiCache提供了两种方式,即RDB和AOF。
在后面提到的AOF方式可以使用,但通常更推荐使用无需备份功能的Multi-AZ复制配置。
关系数据库(快照)
默认启用的方式。
定期将数据库的内容保存到硬盘上(保存为一个名为dump.rdb的二进制文件)。
在重新启动时,数据将从dump.rdb中恢复。
在故障时,从上次备份开始的增量数据将会丢失。
# save "" # RDBに保存しない
save 900 1 # 900秒以内に1回以上の更新があったらRDBに保存する
save 300 10 # 300秒以内に10回以上の更新があったらRDBに保存する
save 60 10000 # 60秒以内に10000回以上の更新があったらRDBに保存する
追加API(AOF)
每次更新处理都会持续保存处理内容。
这样可以减少数据丢失的担忧,但是会降低更新处理的性能。
appendonly yes
(省略)
# appendfsync always # AOFへ常に同期的に書き込む
appendfsync everysec # AOFへ1秒毎に同期的に書き込む
# appendfsync no
(省略)
Redis的使用领域
-
- 有効期限のあるデータを扱う場合
セッション、ワンタイムトークンなど
データ保存時にexpire指定できる
ランキングデータを扱う場合
Sorted Set(ユーザID/スコアなど)を利用する
RDBのorder byより速い
IoTデータの一時保存先として使う場合
Pub/Subを使う場合
Redis和memcached的选择和使用
如果初学者认为Redis更具多功能性,那么选择Redis似乎是不错的。
应该选择使用Redis的情况
-
- 複雑なデータ型が必要な場合
-
- 永続化が必要な場合
-
- フェイルオーバーが必要な場合
- pub/subが必要な場合
应该选择memcached的情况
-
- シンプルなデータ型だけで充分な場合
- マルチスレッドが必要な場合
尝试在本地使用Redis
安装(如果是MacOS)
$ brew install Redis
启动
启动服务器
$ redis-server
启动客户端
$ redis-cli
命令行界面 (命令行界面)
在启动的客户端上进行CLI操作。
这里仅提供基本操作方法。
更详细的操作方法可以参考这篇文章。
每个执行示例中的flushall命令用于删除数据库中的所有键。
String 类型
使用set方法将value注册。
使用get方法获取value。
127.0.0.1:6379> set str1 hello
OK
127.0.0.1:6379> get str1
"hello"
127.0.0.1:6379> flushall
OK
使用setex进行带有过期时间的注册。
使用ttl来确认过期时间。
127.0.0.1:6379> setex str1 10 world
OK
127.0.0.1:6379> ttl str1
(integer) 7
127.0.0.1:6379> ttl str1
(integer) -2
127.0.0.1:6379> get str1
(nil)
127.0.0.1:6379> flushall
OK
使用mset一次性进行多个注册。
使用mget一次性进行多个获取。
127.0.0.1:6379> mset str1 hello str2 world
OK
127.0.0.1:6379> mget str1 str2
1) "hello"
2) "world"
127.0.0.1:6379> flushall
OK
使用incr函数增加数字。
使用decr函数减少数字。
127.0.0.1:6379> set str1 0
OK
127.0.0.1:6379> incr str1
(integer) 1
127.0.0.1:6379> get str1
"1"
127.0.0.1:6379> decr str1
(integer) 0
127.0.0.1:6379> get str1
"0"
127.0.0.1:6379> flushall
OK
列表类型
用 lpush 在列表头部注册一个 value。
用 lrange 指定头部元素和尾部元素进行获取。当指定为 0 和 -1 时获取全部。
用 lpop 获取列表的头部值。
127.0.0.1:6379> lpush list1 abc
(integer) 1
127.0.0.1:6379> lpush list1 def
(integer) 2
127.0.0.1:6379> lrange list1 0 -1
1) "def"
2) "abc"
127.0.0.1:6379> lpop list1
"def"
127.0.0.1:6379> lrange list1 0 -1
1) "abc"
127.0.0.1:6379> flushall
OK
使用rpush命令将value添加到列表的末尾。
使用rpop命令获取列表中的末尾值。
127.0.0.1:6379> rpush list2 abc
(integer) 1
127.0.0.1:6379> rpush list2 def
(integer) 2
127.0.0.1:6379> lrange list2 0 -1
1) "abc"
2) "def"
127.0.0.1:6379> rpop list2
"def"
127.0.0.1:6379> lrange list2 0 -1
1) "abc"
127.0.0.1:6379> flushall
OK
使用LREM进行删除。可以指定要删除的数量。如果数量为0,则删除全部。
127.0.0.1:6379> lrange list1 0 -1
1) "abc"
2) "def"
3) "abc"
127.0.0.1:6379> lrem list1 0 abc
(integer) 2
127.0.0.1:6379> lrange list1 0 -1
1) "def"
127.0.0.1:6379> flushall
OK
集合类型
使用SADD进行注册。
使用SMEMBERS获取所有值。
使用SREM删除值。
127.0.0.1:6379> sadd set1 abc
(integer) 1
127.0.0.1:6379> sadd set1 def
(integer) 1
127.0.0.1:6379> smembers set1
1) "def"
2) "abc"
127.0.0.1:6379> srem set1 abc
(integer) 1
127.0.0.1:6379> smembers set1
1) "def"
127.0.0.1:6379> flushall
OK
由于是集合,因此无法注册相同的值。
127.0.0.1:6379> sadd set1 abc
(integer) 1
127.0.0.1:6379> sadd set1 abc
(integer) 0
127.0.0.1:6379> flushall
OK
排序集合类型
使用zadd命令将score和键值对一起注册。score的值可以是负数。
使用zrange命令指定首尾元素并获取。如果指定为0和-1,则获取全部元素。
使用zrem命令进行删除操作。
127.0.0.1:6379> zadd zset1 5 abc
(integer) 1
127.0.0.1:6379> zadd zset1 -10 def
(integer) 1
127.0.0.1:6379> zrange zset1 0 -1 withscores
1) "def"
2) "-10"
3) "abc"
4) "5"
127.0.0.1:6379> zrem zset1 abc
(integer) 1
127.0.0.1:6379> zrange zset1 0 -1 withscores
1) "def"
2) "-10"
127.0.0.1:6379> flushall
OK
哈希类型
使用hset进行注册。
使用hget获取值。
使用hgetall获取所有哈希。
使用hdel删除哈希。
127.0.0.1:6379> hset hash1 field1 abc
(integer) 1
127.0.0.1:6379> hget hash1 field1
"abc"
127.0.0.1:6379> hset hash1 field2 def
(integer) 1
127.0.0.1:6379> hgetall hash1
1) "field1"
2) "abc"
3) "field2"
4) "def"
127.0.0.1:6379> hdel hash1 field1
(integer) 1
127.0.0.1:6379> hget hash1 field1
(nil)
127.0.0.1:6379> flushall
OK
Python(redis-py)的意思是使用Python语言和redis-py库。
如果是一种知名的语言,通常会有相应的库可供使用,但在这里以Python为例进行总结。
安装
$ sudo pip install redis
连结
有两种连接池的使用方式:使用连接池的方法和不使用连接池的方法。
似乎使用连接池更快。
import redis
pool = redis.ConnectionPool(host='localhost', port=6379, db=0)
r = redis.StrictRedis(connection_pool=pool)
import redis
r = redis.StrictRedis(host='localhost', port=6379, db=0)
操作 – (noun/verb)
在这里只列举了String类型的简单例子。
如果想了解其他类型或更详细的使用方法,可以参考这篇文章。
r.set("key1", "hello")
print(r.get("key1"))
b'hello'
发布/订阅
简述
发布和订阅的缩写。
当一个客户端发布(向频道发送消息)时,订阅该频道的客户端可以接收该消息的功能。
除了作为键值存储外,Redis还具有发布订阅功能。
使用方法
开启服务器。
$ redis-server
启动客户端A并订阅频道。
$ redis-cli
127.0.0.1:6379> SUBSCRIBE sample_channel
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "sample_channel"
3) (integer) 1
启动客户端B并将其发布到频道。
$ redis-cli
127.0.0.1:6379> PUBLISH sample_channel "Hello! World!"
(integer) 1
客户A能够在客户B发布的消息中确认到(★标记)。
$ redis-cli
127.0.0.1:6379> SUBSCRIBE sample_channel
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "sample_channel"
3) (integer) 1
1) "message" ★
2) "sample_channel" ★
3) "Hello! World!" ★
弹性缓存
ElastiCache是AWS提供的关于内存缓存的托管服务。
可以选择使用Redis和memcached作为缓存引擎。
存在节点、分片和集群的单位。
节点 (Node)
缓存服务器。
ElastiCache的最小单位。
根据选择的节点类型,性能(内存和CPU等)会有所不同。
碎片 (Shard)
拥有一个主节点(可读写)和0到5个副本节点(只读)的节点组。
聚类 (jù
整理碎片的群组。
可以为每个集群选择缓存引擎。
可以选择启用或禁用集群模式。
禁用集群模式
这个图示是一个有效的复制品。
- クラスタ1つにシャード1個を持つ
启用集群模式
这幅图是一个具有有效复制效果的示意图。
-
- クラスタ1つにシャード1〜15個を持つ
-
- スケールアウト/スケールイン可能
シャード数の増減により変更
扩大规模/缩小规模
-
- スケールアップ可能
ノードタイプをAPIを利用して変更
スケールダウン不可
多可用区 (Duō qū)
只要是除了t2之外的节点类型,可以选择Multi-AZ部署。节点可以配置到Multi-AZ中。
以前,memcached不支持Multi-AZ部署,但最近也已经支持了,因此Redis在这方面的优势已经丧失了。
当发生障碍时。
当发生障碍时,系统会自动进行故障切换,将故障节点切换到新节点上。
如果主节点故障
-
- リードレプリカの1つ(複数ある場合は最も最新のデータが記録されているものが自動選択される)がプライマリノードに昇格する
-
- フェイルオーバー中はプライマリノードへの書き込みは不可
- 昇格して減った分のリードレプリカは新しく補填される
如果领导复制品出现故障的情况下
-
- 新しいリードレプリカノードを自動生成し、故障したノードから切り替える
- フェイルオーバー中の読み込み処理は他のノードに負荷が集中する
如果整个集群发生故障
-
- シャードもノードも自動で再作成
-
- 永続化していない場合データは失われる
永続化は非推奨なのでどうしても永続化したいデータは定期的にRDBに格納すべし
我试过了
集群模式禁用
-
- クラスターエンジン
Redisを選択
クラスターモードを有効のボタン
チェックつけない
-
- ポート番号
デフォルトの6379
パラメータグループ
cluster.onが付いていないもの
ノードタイプ
検証用のため最も安いもの(t2.micro)を選択
レプリケーション数
リードレプリカの数のこと
2を選んだ場合はクラスタの中にプライマリが1台とリードレプリカが2台生成され、合計3台になる
-
- Multi-AZ
ノードタイプがt2なので選択不可
-
- セキュリティグループ
同一VPC内のEC2インスタンスからの6379を受け入れるセキュリティグループを作成して選択する
同一VPC内のEC2インスタンス以外からも接続はできるがVPNの設定とかめんどい
保管時の暗号化
保管したデータを暗号化するかどうか
送信中の暗号化
EC2インスタンスやノード間の通信を暗号化するかどうか
-
- バックアップ
ノードタイプがt2なのでバックアップは選択不可
-
- メンテナンス
ElastiCacheのパッチ適用が発生した場合に、パッチを適用する時間を指定できる。
運用サービスのメンテナンス時間やリクエストが少ない時間帯に設定するのが良さそう。
通知方法も指定できる。
今回は検証用なので設定しない。
- 最終的にこんな感じ
启用集群模式
我只需要一种选择,在中文中将下面的句子进行意译:
这里只解释与禁用上级集群模式的例子之间有所不同的部分。
-
- クラスターモードを有効のボタン
チェックする
-
- パラメータグループ
cluster.onが付いているもの
ノードタイプ
m3.medium(検証用にMulti-AZやバックアップ機能を確認するために選択)
-
- Multi-AZ
チェックつけて有効化
スロットおよびキースペース
シャードの負荷分散方法を選択する
デフォルトの均等分散を選択
アベイラビリティゾーン
ノード単位でアベイラビリティゾーンを指定可能
今回は指定なし
-
- バックアップ
自動バックアップを有効化
AOF
可以在创建后进行更改的事项以及不可更改的事项。
-
- キャッシュエンジンのバージョン変更
アップグレード可能
ダウングレード不可
パラメータグループ変更可能
バックアップ設定変更可能
通知方法変更可能
シャード数の増減可能
レプリカ数の増減可能
思考
-
- ローカルにインストールするにしてもElastiCacheを利用するにしても簡単にRedisを使い始めることができる
-
- 単純なデータしか扱えない分、覚えることが少ないので学習コストは低い
- とりあえずRedisが使えるようになっておけばmemcachedもいけそう