Redis点滴
最近试验在产品中使用Redis来完成以前MongoDB做的一些工作,发现在大量消息采集的场景下(咱们这次不谈查询什么的),redis比mongoDB表现更好──这里主要是指编程更简便、逻辑更清晰。下面我举一些小例子说说Redis都为我们解决了什么问题,技术上下文关键字
最近试验在产品中使用Redis来完成以前MongoDB做的一些工作,发现在大量消息采集的场景下(咱们这次不谈查询什么的),redis比mongoDB表现更好──这里主要是指编程更简便、逻辑更清晰。下面我举一些小例子说说Redis都为我们解决了什么问题,技术上下文关键字:高并发、分布式。
插入与更新操作的无差别性
Redis的所有SET(包括MSET,HMSET)操作都是:存在则更新,不存在则插入,即insert if not exists。所以在编程的时候开发人员不需要关心所做的操作属于更新还是插入,减免了判断,因此也避免了判断操作可能带来的锁定。
MongoDB也有同样的操作,update操作的upsert参数调为True即可,不过经过测试,MongoDB为查询条件为了索引后使用update with upsert来代替insert操作,效率比光insert要低5倍以上,而redis的HMSET操作的效率要胜出。
GETSET的妙用
上一个经验虽说可以解决这条数据该“插入还是更新”的问题,但需要知道当前操作是否针对某数据的首次操作的需求还不少。例如我的程序会在不同时间接收到同一条消息的不同分片信息包,我需要在收到该消息的首个信息包(发送是无序的)时做些特殊处理。
早些时候的做法是为消息在MongoDB维护一个状态对象,有信息包来的时候就走“上锁->检查消息状态->根据状态决定做不做特殊操作->解锁” 这个流程,虽然同事已经把锁的粒度控制得非常细了,但有锁的程序遇上多实例部署就歇了。
Redis的GETSET是解决这个问题的终极武器,只需要把当前信息包的唯一标识对指定的状态属性进行一次GETSET操作,再判断返回值是否为空则知道是否首次操作。GETSET替我们把两次读写的操作封装成了原子操作,V5啊。
山寨版数据过期策略
我曾经想过要写服务器端的脚本来扩展redis,试图要拿到数据过期的事件,用来做一些回调来处理过期数据,但很快我发现这个不现实。于是我选择通过使用排序集合(SORTEDSET)来实现一个山寨的数据过期策略:需要定时过期的数据,统一添加到一个排序集合:ZADD expiringKey timestamp data。在这里我使用了时间值(毫秒为单位的长整型)作为数据的分数,那么很自然的,早期的数据总会排在集合前面;然后我写一个程序会定时地过来打理这些过期的数据就好了。
存储结构化数据
例如有“通讯录”这样的数据,包含有”name”,”city”,”gender”等8个属性,使用mongoDB保存就很简单,创建一个Document,设置属性后存储即可,而Redis本身并非Document型的DB而是Key Value DB,要存储这种数据,还得在Key上面花一点功夫:使用contact:id:name,contact:id:city,contact:id:gender之类的Key来存储其对应的值。当然,这只是使用redis存储结构化数据最原始的办法,更建议的办法是使用Hash存储,如 hmset contact:id name jeff contact xx@gmail.com gender male。相对set操作而言,hmset既节省了存储空间又提高了存储效率。
使用MongoDB来存储这些数据是小菜一碟,但鉴于第一点经验,我还是愿意使用Redis。
比较可惜的是,目前Redis的Hash存储仅支持字符类型的值,不支持其他数据结构,我非常期待它日后会支持其他数据结构,甚至支持Hash的嵌套。关于这点,@wuvist 同学认为十分有可能。
小结
上面这些Case都只是Redis牛刀小用,但实际上给程序带来的便利是非常明显的,最明显的就是可以把原来的程序上使用的锁都抛弃掉,甚至直接支持分布式运行和水平扩展了。
顺便在此小结一点高并发分布式应用程序编写的一些推荐的注意事项吧,当然这是我的个人偏好并结合了一些特定业务领域的性质:
1. 程序对资源最好是只读或只写,明确分工。不要在一个程序里同时对资源进行读写,除非是原子操作,如GETSET。
2. 写操作中,插入与更新最好是无差别的,避免程序对此进行行判断,破坏操作的原子性。
3. 更新过程中尽最不要对更新值和原值进行比较,还是关乎操作的原子性,如果真要进行比较,有两种方案供参考。
1). 更新时,为字段追加新数据,使用集合(如果是数值使用排序集合更好)来存储;比较的逻辑交给读取的程序处理。
2). 使用CAS,类似乐观锁,实现多进程数据安全控制。如果目标资源的服务器支持最佳。
4. 还是那一句,避免在程序里面使用锁。逼不得已就用分布式锁吧。
5. 多线程是万恶之源,要慎用,一条线程能把CPU跑满才是真牛,多核、扩容时可考虑多进程。
原文地址:Redis点滴, 感谢原作者分享。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









Redisクラスターモードは、シャードを介してRedisインスタンスを複数のサーバーに展開し、スケーラビリティと可用性を向上させます。構造の手順は次のとおりです。異なるポートで奇妙なRedisインスタンスを作成します。 3つのセンチネルインスタンスを作成し、Redisインスタンスを監視し、フェールオーバーを監視します。 Sentinel構成ファイルを構成し、Redisインスタンス情報とフェールオーバー設定の監視を追加します。 Redisインスタンス構成ファイルを構成し、クラスターモードを有効にし、クラスター情報ファイルパスを指定します。各Redisインスタンスの情報を含むnodes.confファイルを作成します。クラスターを起動し、CREATEコマンドを実行してクラスターを作成し、レプリカの数を指定します。クラスターにログインしてクラスター情報コマンドを実行して、クラスターステータスを確認します。作る

Redisはハッシュテーブルを使用してデータを保存し、文字列、リスト、ハッシュテーブル、コレクション、注文コレクションなどのデータ構造をサポートします。 Redisは、スナップショット(RDB)を介してデータを維持し、書き込み専用(AOF)メカニズムを追加します。 Redisは、マスタースレーブレプリケーションを使用して、データの可用性を向上させます。 Redisは、シングルスレッドイベントループを使用して接続とコマンドを処理して、データの原子性と一貫性を確保します。 Redisは、キーの有効期限を設定し、怠zyな削除メカニズムを使用して有効期限キーを削除します。

Redis-Serverが見つからない問題を解決するための手順:インストールを確認して、Redisが正しくインストールされていることを確認します。環境変数Redis_hostとredis_portを設定します。 Redis Server Redis-Serverを起動します。サーバーがRedis-Cli pingを実行しているかどうかを確認します。

Redisのすべてのキーを表示するには、3つの方法があります。キーコマンドを使用して、指定されたパターンに一致するすべてのキーを返します。スキャンコマンドを使用してキーを繰り返し、キーのセットを返します。情報コマンドを使用して、キーの総数を取得します。

Redisバージョン番号を表示するには、次の3つの方法を使用できます。(1)情報コマンドを入力し、(2) - versionオプションでサーバーを起動し、(3)構成ファイルを表示します。

Redisソースコードを理解する最良の方法は、段階的に進むことです。Redisの基本に精通してください。開始点として特定のモジュールまたは機能を選択します。モジュールまたは機能のエントリポイントから始めて、行ごとにコードを表示します。関数コールチェーンを介してコードを表示します。 Redisが使用する基礎となるデータ構造に精通してください。 Redisが使用するアルゴリズムを特定します。

Redis指令を使用するには、次の手順が必要です。Redisクライアントを開きます。コマンド(動詞キー値)を入力します。必要なパラメーターを提供します(指示ごとに異なります)。 Enterを押してコマンドを実行します。 Redisは、操作の結果を示す応答を返します(通常はOKまたは-ERR)。

Redis Orderedセット(ZSET)は、並べ替えられた要素を保存し、関連するスコアでソートするために使用されます。 zsetを使用する手順には次のものがあります。1。zsetを作成します。 2。メンバーを追加します。 3.メンバースコアを取得します。 4。ランキングを取得します。 5.ランキング範囲のメンバーを取得します。 6.メンバーを削除します。 7.要素の数を取得します。 8。スコア範囲のメンバーの数を取得します。
