Redis简介、与memcached比较、存储方式、应用场景、生产经验教训、安全设置、key的建议、安装和常用数据类型介绍、ServiceStack.Redis使用(1)

时间:2022-02-17 07:48:59

1.NOSQL简介

nosql的产生并不是要彻底的代替关系型数据库,而是作为传统关系型数据库的一个补充。

Facebook和360使用Cassandra来存储海量社交数据

Twitter在其url抓取系统里综合运用了Cassandra、memcached

新浪微博使用Redis

淘宝使用hbase,并改进研制出自己品牌的nosql产品Oceanbase

mongodb被广泛用于存储非结构化数据

memcachedb是新浪网基于memcached开发的一个开源项目。给memcached分布式缓存服务器添加了Berkeley DB的持久化存储机制

和异步主辅复制机制,让memcached具备了事务恢复能力、持久化能力和分布式复制能力,非常适合于需要超高性能读写速度,

但是 不需要严格事务约束,能够被持久化保存的应用场景。例如,memcachedb被应用在新浪博客上。如果对memcached有持久化需求,

可以考虑使用memcachedb。

2.非关系型的特点

(1)数据模型比较简单

(2)对数据库性能要求较高

(3)不需要高度的数据一致性

(4)对于给定的key,比较容易映射复杂值的环境

2.Redis简介

Redis是一个开源的,使用C语言编写,面向“键/值”对类型数据的分布式NoSQL数据库系统,特点是高性能,持久存储,适应高并发的应用场景。Redis纯粹为应用而产生,它是一个高性能的key-value数据库,并且提供了多种语言的API性能测试结果表示SET操作每秒钟可达110000次,GET操作每秒81000次(当然不同的服务器配置性能不同)。

redis目前提供五种数据类型:string(字符串),list(链表), Hash(哈希),set(集合)及zset(sorted set)  (有序集合)

3.Redis与Memcached的比较

(1)Memcached是多线程,而Redis使用单线程.

(2)Memcached使用预分配的内存池的方式,Redis使用现场申请内存的方式来存储数据,并且可以配置虚拟内存。

(3)Redis可以实现持久化,主从复制,实现故障恢复。

(4)Memcached只是简单的key与value,但是Redis支持数据类型比较多。

(5)Redis的存储分为内存存储、磁盘存储 .从这一点,也说明了Redis与Memcached是有区别的。Redis 与Memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改 操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。

3.Redis存储方式

Redis是一个支持持久化的内存数据库,也就是说redis需要经常将内存中的数据同步到硬盘中来保证持久化。

Redis支持两种持久化方式.

(1):snapshotting(快照) rdb 也是默认方式.(把数据做一个备份,将数据存储到文件)

(2)Append-only file(缩写aof)的方式

快照是默认的持久化方式,这种方式是将内存中数据以快照的方式写到二进制文件中,默认的文件名称

为dump.rdb.可以通过配置设置自动做快照持久化的方式。我们可以配置redis在n秒内如果超过m个key

键修改就自动做快照.

aof方式:由于快照方式是在一定间隔时间做一次的,所以如果redis意外down掉的话,就会丢失最后一次

快照后的所有修改。aof比快照方式有更好的持久化性,是由于在使用aof时,redis会将每一个收到的

写命令都通过write函数追加到文件中,当redis重启时会通过重新执行文件中保存的写命令来在内存中重建

整个数据库的内容。

当然由于os会在内核中缓存write做的修改,所以可能不是立即写到磁盘上。真阳aof方式的持久化

也还是有可能会丢失部分修改。可以通过配置文件告诉redis我们想要通过fsync函数强制os写入到磁盘

的时机。

4.redis的应用场景

1.redis最佳使用场景是全部数据加载到内存中使用

2.redis更多场景是作为memcached的替代品来使用

3.数据比较重要,对数据一致性有一定的要求的业务

4.当需要除key/value之外的更多数据类型支持时,使用redis更合适

5.需要提供主从同步以及负载均衡分布式应用的场景(redis主从同步)

比如:计数、缓存服务、展示最近、最热、点击率最高、活跃度最高等条件的top list、用户最近访问记录、相关列表、消息队列、

粉丝列表、商品分类。

redis在微博中的应用

应用场景:

计数器

微博(评论、转发、阅读、赞等)

用户(粉丝、关注、收藏、双向关注等)

好友关系

5.redis的生产经验教训

1.要进行主从同步配置,在出现服务故障时可以切换

2.在master禁用数据持久化,只需在slave上配置数据持久化。

3.物理内存+虚拟内存不足,这个时候dump一直死着,时间久了机器挂掉,这个情况就是灾难。最少64-128G内存,SSD硬盘。

4.当redis物理内存使用超过内存总容量的3/5就会开始比较危险了,就开始做swap,内存碎片大。

5.当达到最大内存时,会清空带有过期时间的key,即使key未到过期时间

6.redis和db同步写的问题,先写db,后写redis,因为写内存基本上没有问题。

redis 默认有16个库,从0开始,使用select 1 命令切换到第二个库

使用help命令查看帮助命令,help @string 查看所有string类型的,help set  查看set命令

6.redis安全

我们找到redis.conf中# requirepass foobared  设置密码requirepass 123456

使用auth 123456命令后可以进入

C:\Users\yuxl>redis-cli

127.0.0.1:6379> set key 1

(error) NOAUTH Authentication required.

127.0.0.1:6379> auth 123456

也可以使用这种方式

C:\Users\yuxl>redis-cli -a 123456

127.0.0.1:6379> set key1 1

OK

别的安全措施可以在redis.conf中将命令改名字或者禁用,找到# rename-command CONFIG "",比如rename-command get myget  将get命令改为myget

7.关于redis key的几条建议

1.太长的键值不是个好主意,例如1024字节的键值就不是个好主意,不仅因为消耗内存,而且在数据中查找这类键值的计算成本很高。

2.太短的键值通常也不是好主意,不易阅读,对内存消耗影响不是很大

坚持一种模式。如:“object-type:id:field”,“user:1000:password”,我喜欢对多单词的字段名中加上一个点,就像这样:comment:1234:reply.to,长度10-20,value建议string不必要超过2k,set sortedset不必要超过5000个元素

8.Redis安装

最新下载地址:https://github.com/ServiceStack/redis-windows

下载Redis:https://github.com/MicrosoftArchive/redis/releases

redis-server.exe:服务程序

redis-check-dump.exe:本地数据库检查

redis-check-aof.exe:更新日志检查

redis-benchmark.exe:性能测试,用以模拟同时由N个客户端发送M个 SETs/GETs 查询.

redis-cli.exe: 服务端开启后,我们的客户端就可以输入各种命令测试了

打开一个cmd窗口,使用cd命令切换到指定目录(F:\Redis)
运行 redis-server.exe redis.conf 
 
重新打开一个cmd窗口,使用cd命令切换到指定目录(F:\Redis)运行 redis-cli.exe -h 127.0.0.1 -p 6379,其中 127.0.0.1是本地ip,6379是redis服务端的默认端口 (这样可以开启一个客户端程序进行特殊指令的测试).
可以将此服务设置为windows系统服务,下载Redis服务安装软件,安装即可。
 
C#调用
程序包管理器控制台
PM> Install-Package ServiceStack.Redis
 
9.Redis常用数据类型
Redis最为常用的数据类型主要有以下五种:
String、Hash、List、Set、SortedSet
String是最常用的一种数据类型,普通的key/value存储都可以归为此类 。一个Key对应一个Value,string类型是二进制安全的。Redis的string可以包含任何数据,比如jpg图片(生成二进制)或者序列化的对象
 
Hash是一个string 类型的field和value的映射表。hash特别适合存储对象。相对于将对象的每个字段存成单个string 类型。一个对象存储在hash类型中会占用更少的内存,并且可以更方便的存取整个对象。作为一个key value存在,很多开发者自然的使用set/get方式来使用Redis,实际上这并不是最优化的使用方法。尤其在未启用VM情况下,Redis全部数据需要放入内存,节约内存尤其重要.
 
list是一个链表结构,主要功能是push,pop,获取一个范围的所有的值等,操作中key理解为链表名字。 Redis的list类型其实就是一个每个子元素都是string类型的双向链表。我们可以通过push,pop操作从链表的头部或者尾部添加删除元素,这样list既可以作为栈,又可以作为队列。Redis list的实现为一个双向链表,即可以支持反向查找和遍历,更方便操作,不过带来了部分额外的内存开销,Redis内部的很多实现,包括发送缓冲队列等也都是用的这个数据结构
 
set是string类型的无序集合。set是通过hash table实现的,添加,删除和查找,对集合我们可以取并集,交集,差集.
 
sorted set 是set的一个升级版本,它在set的基础上增加了一个顺序的属性,这一属性在添加修改   .元素的时候可以指定,每次指定后,zset(表示有序集合)会自动重新按新的值调整顺序。可以理解为有列的表,一列存 value,一列存顺序。操作中key理解为zset的名字.
Redis sorted set的使用场景与set类似,区别是set不是自动有序的,而sorted set可以通过用户额外提供一个优先级(score)的参数来为成员排序,并且是插入有序的,即自动排序。当你需要一个有序的并且不重复的集合列表,那么可以选择sorted set数据结构 
 
事例代码:
 class Program
{
static void Main(string[] args)
{
RedisClient redisClient = new RedisClient("127.0.0.1",); #region 存储字符串类型和自定义类型
//redisClient.Set<string>("name", "yxl");
//Console.WriteLine(redisClient.Get<string>("name")); //UserInfo userInfo = new UserInfo() { UserName = "zhangsan", UserPwd = "1111" };// (底层使用json序列化)
//redisClient.Set<UserInfo>("userInfo", userInfo);
//UserInfo user = redisClient.Get<UserInfo>("userInfo");
//Console.WriteLine(user.UserName); //List<UserInfo> list = new List<UserInfo>() { new UserInfo() { UserName = "lisi", UserPwd = "111" }, new UserInfo() { UserName = "wangwu", UserPwd = "123" } };
//redisClient.Set<List<UserInfo>>("list", list);
//List<UserInfo> userInfoList = redisClient.Get<List<UserInfo>>("list");
//foreach (UserInfo item in userInfoList)
//{
// Console.WriteLine(item.UserName);
//} #endregion #region Hash // redisClient.SetEntryInHash("userInfoId", "name", "yxlhashName");
// redisClient.SetEntryInHash("userInfoId", "name2", "yxlhashName");
// List<string> hashKeys = redisClient.GetHashKeys("userInfoId");
//List<string> hashValues = redisClient.GetHashValues("userInfoId");
//long hashCount = redisClient.GetHashCount("userInfoId");
// Console.WriteLine(hashCount);//2
// foreach (string hashKey in hashKeys)
// {
// Console.WriteLine(hashKey);//name,name2
// }
// foreach (string hashValue in hashValues)
// {
// Console.WriteLine(hashValue);//yxlhashName,yxlhashName
// }
#endregion #region List类型
#region 队列,先进先出 //redisClient.EnqueueItemOnList("name1", "zhangsan");
//redisClient.EnqueueItemOnList("name1", "lisi");
//long length = redisClient.GetListCount("name1");
//for (int i = 0; i < length; i++)
//{
// Console.WriteLine(redisClient.DequeueItemFromList("name1"));
//}
#endregion #region 栈,先进后出
//redisClient.PushItemToList("name1", "zhangsan");
//redisClient.PushItemToList("name1", "lisi");
//long length = redisClient.GetListCount("name1");
//for (int i = 0; i < length; i++)
//{
// Console.WriteLine(redisClient.PopItemFromList("name1"));
//}
#endregion
#endregion #region Set类型,无序集合,集合我们可以取并集,交集,差集.
#region 普通存储
//redisClient.AddItemToSet("a3", "ddd");
//redisClient.AddItemToSet("a3", "ccc");
//redisClient.AddItemToSet("a3", "tttt");
//redisClient.AddItemToSet("a3", "sssh");
//redisClient.AddItemToSet("a3", "hhhh");
//System.Collections.Generic.HashSet<string> hashset = redisClient.GetAllItemsFromSet("a3");
//foreach (string str in hashset)
//{
// Console.WriteLine(str);
//}
#endregion #region 取并集
//redisClient.AddItemToSet("a3", "ddd");
//redisClient.AddItemToSet("a3", "ccc");
//redisClient.AddItemToSet("a3", "tttt");
//redisClient.AddItemToSet("a3", "sssh");
//redisClient.AddItemToSet("a3", "hhhh");
//redisClient.AddItemToSet("a4", "hhhh");
//redisClient.AddItemToSet("a4", "h777"); //System.Collections.Generic.HashSet<string> hashset = redisClient.GetUnionFromSets(new string[] { "a3", "a4" });
//foreach (string str in hashset)
//{
// Console.WriteLine(str);
//}
#endregion #region 取交集
//redisClient.AddItemToSet("a3", "ddd");
//redisClient.AddItemToSet("a3", "ccc");
//redisClient.AddItemToSet("a3", "tttt");
//redisClient.AddItemToSet("a3", "sssh");
//redisClient.AddItemToSet("a3", "hhhh");
//redisClient.AddItemToSet("a4", "hhhh");
//redisClient.AddItemToSet("a4", "h777");
//System.Collections.Generic.HashSet<string> hashset = redisClient.GetIntersectFromSets(new string[] { "a3", "a4" });
//foreach (string str in hashset)
//{
// Console.WriteLine(str);
//}
#endregion #region 取差集
//redisClient.AddItemToSet("a3", "ddd");
//redisClient.AddItemToSet("a3", "ccc");
//redisClient.AddItemToSet("a3", "tttt");
//redisClient.AddItemToSet("a3", "sssh");
//redisClient.AddItemToSet("a3", "hhhh");
//redisClient.AddItemToSet("a4", "hhhh");
//redisClient.AddItemToSet("a4", "h777");
//System.Collections.Generic.HashSet<string> hashset = redisClient.GetDifferencesFromSet("a3",new string[] { "a4" });
////返回存在于第一个集合(a3),但是不存在于其他集合(a4)的数据
//foreach (string str in hashset)
//{
// Console.WriteLine(str);
//}
#endregion
#endregion #region Sorted Set类型
//redisClient.AddItemToSortedSet("a5", "ffff");
//redisClient.AddItemToSortedSet("a5", "bbbb");
//redisClient.AddItemToSortedSet("a5", "gggg");
//redisClient.AddItemToSortedSet("a5", "cccc");
//redisClient.AddItemToSortedSet("a5", "waaa");
//System.Collections.Generic.List<string> list = redisClient.GetAllItemsFromSortedSet("a5");
//foreach (string str in list)
//{
// Console.WriteLine(str);
//} #endregion } public class UserInfo
{
public string UserName { get; set; }
public string UserPwd { get; set; }
}
}

Redis简介、与memcached比较、存储方式、应用场景、生产经验教训、安全设置、key的建议、安装和常用数据类型介绍、ServiceStack.Redis使用(1)的更多相关文章

  1. Redis常用数据类型介绍、使用场景及其操作命令

    Redis常用数据类型介绍.使用场景及其操作命令 本文章同时也在cpper.info发布. Redis目前支持5种数据类型,分别是: 1.String(字符串) 2.List(列表) 3.Hash(字 ...

  2. Redis简介与Memcached的比较

    Redis简介 Redis是一个开源的,使用C语言编写,面向“键/值”对类型数据的分布式NoSQL数据库系统,特点是高性能,持久存储,适应高并发的应用场景.Redis纯粹为应用而产生,它是一个高性能的 ...

  3. Memcached数据存储方式

    1. memcached的数据存储方式被称为Slab Allocator,其基本方式是: ①:先把内存分成很多Slab,这个大小是预先规定好的,已解决内存碎片的问题.分配给Slab的内存空间被称为Pa ...

  4. 使用redis作为Return存储方式

    Return组件可以理解为SaltStack系统对执行Minion返回后的数据进行存储或者返回给其他程序,它支持多种存储方式,比如MySQL.Redis.Memcache等,通过Return我们可以对 ...

  5. Apache Hive 存储方式、压缩格式

    简介: Apache hive 存储方式跟压缩格式! 1.Text File hive> create external table tab_textfile ( host string com ...

  6. 【Redis】一、Redis简介及五种数据类型

    (一)Redis简介   Redis(Remote Dictionary Server)是一个使用ANSI C语言编写.遵守BSD协议.支持网络.可基于内存亦可持久化的日志型.Key-Value的开源 ...

  7. NoSQL数据库:Redis内存使用优化与存储

    Redis常用数据类型 Redis最为常用的数据类型主要有以下五种: ●String ●Hash ●List ●Set ●Sorted set 在具体描述这几种数据类型之前,我们先通过一张图了解下Re ...

  8. Redis入门(一)-Redis简介

    最近几年,Rddis非常的火,受到广大中大型公司,特别是互联网公司的青睐.而作为后端开发,如果你不知道Redis或不会用,没用过,你都不好意思出去找工作.可想而知Redis对于IT行业意义多么重大.对 ...

  9. Docker存储方式选型建议

    转自:https://segmentfault.com/a/1190000007168476 第一部分 问题诊断 事情从一次实施项目说起,我们需要帮助客户将他们的应用容器化并在数人云平台上发布此应用. ...

随机推荐

  1. ios枚举规范

  2. VS的快捷键F12改成和ECLIPSE一样用ctrl&plus;点击下载线

    安装resharper 插件即可 不过这个插件是收费的,可免费体验30天

  3. ipone5 无法安装ipa软件

    iphone5s软件无法安装解决方法一,点击设置 - 通用 - 访问限制,先关闭“安装应用程序”选项,再打开,把后台应用程序刷新也关了,测试. iphone5s软件无法安装解决方法二,点击设置 - 通 ...

  4. 读书笔记——Windows环境下32位汇编语言程序设计(6)使用浮点指令进行64位除法

    罗云彬 典藏版Page192,mark下. 这段代码看不懂,手册上根本没有fdivr不带操作数的指令. .data dqTickCounter1 dq ? dqTickCounter2 dq ? dq ...

  5. PAT-乙级-1037&period; 在霍格沃茨找零钱(20)

    1037. 在霍格沃茨找零钱(20) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue 如果你是哈利·波特迷,你会知 ...

  6. CSS3兼容IE的大杀器

    经过长久以来的不懈努力,我终于成功的将selectivizr与PIE这两个解决css3的利器进行了深度的整合,大大降低了使用难度 <!--[if lte IE 9]><script ...

  7. ant&plus;eclipse知识点详解及使用案例

    ant的优点和地位就不再阐述,下面直接上知识点: 在java中使用xml文件开发,有以下基本语法 (1)project:每个ant程序有且只有一个此标签,而且是类似于html的总标签,有name,de ...

  8. SAP QA32 做使用决策系统报错:分类数据的不一致性&equals;&gt&semi;交易终止

    SAP QA32 做使用决策系统报错:分类数据的不一致性=>交易终止 QA32,对如下检验批做处理,系统报错, 试图使用MSC3N去显示这个批次主数据,同样报错, 原因在于批次的分类数据产生后, ...

  9. php 将数组转换网址URL参数

    $array =array ( 'id' =123, 'name' = 'dopost' );echo http_build_query( $array );//得到结果id=123name=dopo ...

  10. &lbrack;svc&rsqb;&lbrack;jk&rsqb;磁盘的iops和吞吐量&lpar;Throught&rpar;指标

    参考 另参考 IOPS (Input/Output Per Second)即每秒的输入输出量(或读写次数),是衡量磁盘性能的主要指标之一.IOPS是指单位时间内系统能处理的I/O请求数量,一般以每秒处 ...