粗略了解Redis入门~关于数据结构和主要功能~
由于在工作中使用了一个称为Redis的中间件作为缓存服务器,但是我只是凭感觉在使用,所以决定系统地学习一下。
由于在文章中过度使用表格,建议在电脑上阅读。在手机上查看表格会比较困难呢…
Redis是什么?
内存键值存储
由于是内存存储,如果重启Redis,则存储的数据会全部消失(易挥发性)。
(如果进行后续的持久化操作,则不受此限制)
Redis的架构
有Redis Server和Redis Client。
Redis Server默认在6379端口等待连接。
我们可以通过telnet连接到6379端口并执行命令来操作Redis Server。
它是单线程的事件驱动。
只使用一个CPU核心。
可以在Redis中处理的数据结构
在Redis中,我们可以使用键和值的对来存储数据。
有多种数据结构可以作为值来处理。
SET
GET
hashesフィールドと値のマップ。HSET
HGET
lists文字列型のリスト。LPUSH
RPUSH
LRANGE
sets順不同の集合。メンバの重複を許可しない。SADD
SINTER
SUNION
sorted sets文字列型の集合。 ZADD
ZREM
bit arraysbitの配列。ビット単位で操作できる。BITFIELD
hyperloglogsユニークなデータを数えるためのデータ構造。HLLアルゴリズムを使用し高速かつ省メモリで推定できるPFADD
PFCOUNT
geospatial indexes位置情報(緯度、経度、名前) 。中心位置と半径を指定して検索などが出来る。GEOADD
GEORADIUS
streams時系列データ。発生時刻+フィールドと値のマップ。XADD
XREVRANGE
只需一个选项, 以下是中文本地化的释义:
通过查看命令前缀,大致可以了解所处理的数据结构。例如,H代表哈希表,X代表时序数据等。
通过巧妙地利用这些数据结构,我们可以将Redis用于不仅仅是作为缓存服务器,还可以用于互斥锁管理和排序处理。
关于配置文件
配置文件位于/etc/redis.conf。
对于Docker容器,请将其设置为/usr/local/etc/redis/redis.conf。
以以下格式描述设置(称为指令)
keyword argument1 argument2 ... argumentN
如果文件不存在,将使用默认设置。
以下是 Redis 版本 5.0.3 的設定指令清單,以及其含義和使用目的(在 GitHub 上 antirez/redis 的 redis/redis.conf 文件中)。
Redisの主な機能
大致上有七个
EVAL
コマンドとEVALSHA
コマンドでLuaスクリプトを実行できるLRU evictionメモリ使用量が上限に達した際に、使われていないデータを追い出してメモリを確保する仕組み。transactionsコマンドをまとめて発行する仕組み(別名パイプライン)persistenceRedisサーバを再起動してもデータを維持するための仕組み。Redis SentinelRedisサーバの死活監視/通知および自動フェイルオーバー機能を提供する仕組みRedis Cluster複数のRedisサーバにデータを分散させる仕組み复制
マスタースレーブ間でデータを同期する仕組み
マスタースレーブ間のリンクが切れた場合、スレーブは自動的にマスターに再接続する。
可用性を向上させるために使用する。
Lua脚本编程
EVALコマンドとEVALSHAコマンドでLuaスクリプトを実行できる
EVALコマンドはLuaスクリプトを直接実行できる
EVALSHAコマンドはあらかじめ登録しておいたLuaスクリプトを呼び出す事ができる。
SCRIPT LOADコマンドを使用してLuaスクリプトを登録する。
登録時にSHA1ハッシュが発行されるので、これを使って、EVALSHAコマンドで呼び出す事ができる。
アプリケーションからSHA1ハッシュでLuaスクリプトを呼び出す事で
「Luaでデータを加工してから保存」といった事ができる。
実行中は他のリクエストをブロックする。
最近最少使用(LRU)的驱逐
メモリ使用量が上限に達した際に、使われていないデータを追い出してメモリを確保する仕組み。
LRUとはLeast Recently Usedの略で「最近最も使われなかったもの」を表す
maxmemoryディレクティブでメモリ使用量の上限を設定できる。
メモリ使用量の上限に達した際のふるまいはmaxmemory-policyディレクティブで設定できる。
デフォルトでは、maxmemory-policyがnoevictionになっており当該機能は使われない。
交易
コマンドをまとめて発行する仕組み(別名パイプライン)
RDBMSとは異なり、ロールバックやロックは出来ない。
1連の処理の原子性は保証される(全て実行 or 全て未実行)が、データの整合性は担保されない。
コマンドをまとめて発行するのでラウンドトリップが少なくなりパフォーマンスが向上する
使用MULTI命令开始事务。
使用EXEC命令批量执行事务中的命令。
坚持不懈
Redisを再起動してもデータを維持するための仕組み。
RDBとAOFと呼ばれる2つの方式がある
RDBに関連する設定(ディレクティブ)
save 300 10
save 60 10000dbfilenameファイル名dump.rdbdir保存先ディレクトリ(AOFと共通)./rdbcompression圧縮を行うかyes
AOFに関連する設定(ディレクティブ)
Redis哨兵
提供了 Redis 服务器的存活监控/通知和自动故障转移功能的机制。
Redis 集群
将数据分散在多个Redis服务器(称为节点)上的机制(分片)
根据数据的键值将其分配到相应的节点上
相同的数据不会被存储在多个节点上。
暂时试试摸一下
暂时用Docker在Redis上建立一个服务器。
Docker Hub。
docker run --name some-redis -d redis
我搭建了服务器,但意识到没有可用于连接的客户端。
似乎有一个叫做redis-cli的工具可以用来查询。
似乎还有其他一些图形界面的工具,但首先尝试使用看起来比较标准的redis-cli。
在浏览Docker Hub时,发现了一种针对上述容器可以使用redis-cli进行连接的启动方法,于是尝试使用它。
docker run -it --link some-redis:redis --rm redis redis-cli -h redis -p 6379
据说可以为值设定有效期限,超过有效期限的值可以自动删除。
尝试通过PHP连接到Redis服务器。
有很多用于处理PHP和Redis的库。 duō yú PHP hé Redis de tú).
在Laravel中支持predis/predis包和Redis PHP扩展。
虽然PHP扩展的处理更快,但安装更复杂。
这次我们将从前者的predis包中尝试使用redis。
以下是一個我試著寫的PHP腳本。
我註冊了幾個資料結構並且通過var_dump來輸出它們。
該輸出在var_dump下面的一行中有評論。
<?php
require_once 'vendor/autoload.php';
// Redisサーバに接続
$redis = new Predis\Client([
'host' => 'some-redis',
'port' => 6379,
]);
// redisの全データ削除
$redis->flushdb();
/*
* データ構造:文字列
*/
$redis->set('my-key', 'my-value');
var_dump($redis->get('my-key'));
// 出力: 'my-value'
/*
* データ構造:リスト
*/
$redis->rpush('my-list', 'first');
$redis->rpush('my-list', 'second');
$redis->rpush('my-list', 'third');
var_dump($redis->llen('my-list'));
// 出力: 3
var_dump($redis->lrange('my-list', 0, 2));
// 出力: 'first', 'second', 'third'
/*
* データ構造:セット
*/
$redis->sadd('my-set', 'alpha');
$redis->sadd('my-set', 'bravo');
$redis->sadd('my-set', 'charlie');
var_dump($redis->smembers('my-set'));
// 出力: 'alpha', 'charlie', 'bravo'
/*
* データ構造:ハッシュ
*/
$redis->hmset('my-hash', [
'title' => 'redisを分かった気になる本',
'author' => 'me',
'publisher' => 'sya-syu-syo',
'publish-date' => '2018-01-01 01:01:01',
]);
var_dump($redis->hmget('my-hash', [
'title',
'author',
'publisher'
]));
// 出力: 'redisを分かった気になる本', 'me', 'sya-syu-syo'
/**
* Pipelineを使用して、複数のコマンドをまとめて発行する
*/
$replies = $redis->pipeline(function($pipe) {
$pipe->incr('my-counter');
$pipe->incr('my-counter');
$pipe->incr('my-counter');
$pipe->incr('my-counter');
$pipe->incr('my-counter');
});
var_dump($redis->get('my-counter'));
// 出力: 5
總結
Redis不仅可以用作缓存服务器哦!!!