
1什么是Redis一款内存高速缓存数据库(全称远程数据服务);使用C语言编写Redis是一个key-value存储系统,它支持丰富的数据类型,如:string、list、set、zset(sortedset)、hash等2Redis特点Redis以内存作为数据存储介质,所以读写数据的效率极高,远远超过数据库。以设置和获取一个256字节字符串为例,它的读取速度可高达110000次/s,写速度高达81000次/s。储存在Redis中的数据是持久化的,断电或重启后,数据也不会丢失。-----Redis的存储分为内存存储、磁盘存储和log文件三部分,重启后,Redis可以从磁盘重新将数据加载到内存中。(实现持久化)3Redis应用场景,它能做什么在服务器中常用来存储一些需要频繁调取的数据,这样可以大大节省系统直接读取磁盘来获得数据的I/O开销,更重要的是可以极大提升速度。(拿大型网站来举个例子,比如a网站首页一天有100万人访问,其中有一个板块为推荐新闻。要是直接从数据库查询,那么一天就要多消耗100万次数据库请求。上面已经说过,Redis支持丰富的数据类型,所以这完全可以用Redis来完成,将这种热点数据存到Redis(内存)中,要用的时候,直接从内存取,极大的提高了速度和节约了服务器的开销。)使用Redis有哪些好处?(1)速度快,因为数据存在内存中,类似于HashMap,HashMap的优势就是查找和 *** 作的时间复杂度都是O(1)(2)支持丰富数据类型,支持string,list,set,sortedset,hash(3)支持事务, *** 作都是原子性,所谓的原子性就是对数据的更改要么全部执行,要么全部不执行(4)丰富的特性:可用于缓存,消息,按key设置过期时间,过期后将会自动删除redis相比memcached有哪些优势?(1)memcached所有的值均是简单的字符串,redis作为其替代者,支持更为丰富的数据类型(2)redis的速度比memcached快很多(3)redis可以持久化其数据redis常见性能问题和解决方案:(1)Master最好不要做任何持久化工作,如RDB内存快照和AOF日志文件(2)如果数据比较重要,某个Slave开启AOF备份数据,策略设置为每秒同步一次(3)为了主从复制的速度和连接的稳定性,Master和Slave最好在同一个局域网内(4)尽量避免在压力很大的主库上增加从库(5)主从复制不要用图状结构,用单向链表结构更为稳定4redis和mysql的区别总结(1)类型上从类型上来说,mysql是关系型数据库,redis是缓存数据库(2)作用上mysql用于持久化的存储数据到硬盘,功能强大,但是速度较慢redis用于存储使用较为频繁的数据到缓存中,读取速度快(3)需求上mysql和redis因为需求的不同,一般都是配合使用。5redis和mysql要根据具体业务场景去选型redis和mysql要根据具体业务场景去选型mysql:数据放在磁盘redis:数据放在内存mysql支持sql查询,可以实现一些关联的查询以及统计;redis对内存要求比较高,在有限的条件下不能把所有数据都放在redis;mysql偏向于存数据,redis偏向于快速取数据,但redis查询复杂的表关系时不如mysql,所以可以把热门的数据放redis,mysql存基本数据
主备切换的过程中( 异步复制,脑裂 ),可能会导致数据丢失
因为 master -> slave的复制是异步 的(客户端发送给redis,主节点数据同步到内存中后就返回成功了)
所以可能有部分数据还没复制到slave,master就宕机了,此时master内存中的数据也没了,这些部分数据就丢失了。
脑裂,也就是说,某个master所在机器突然脱离了正常的网络,跟其他slave机器不能连接,但是实际上master还运行着(这种分布式中间件脑裂是常规 *** 作,类似的,比如 rabiitmq脑裂 )
此时哨兵可能就会认为master宕机了,然后开启选举,将其他slave切换成了master
这个时候,集群里就会有两个master,也就是所谓的脑裂
此时虽然某个slave被切换成了master,但是可能client还没来得及切换到新的master,还继续写向旧master的数据,然后旧master再次恢复的时候,会被作为一个slave挂到新的master上去,自己的数据会清空,重新从新的master复制数据,就导致了我们之前在脑裂时候向旧master写的数据全部都丢失了。
解决以上两种情况redis数据丢失的问题 都是靠 以下两个参数配置将数据损失降到最低。
min-slaves-to-write x
min-slaves-max-lag y
(要求y秒内至少有x个slave同步接收到这个数据,比如x=1,y=10)
有了min-slaves-max-lag这个配置,就可以确保说,一旦slave复制数据和ack延时太长,就 认为 可能master宕机后 损失 的数据 太多 了,那么就 拒绝 新的 写 请求,这样可以把master 宕机时 由于部分数据未同步到slave导致的数据丢失的损失 降低的可控范围内 ,但是 仅有一个从库要谨慎设置1,只有一个从库且要去维护的时候,请先设置 最少写从库的个数为0,再去维护从库
如果一个master出现了脑裂,跟其他slave丢了连接,那么上面两个配置可以确保说,如果不能继续给指定数量的slave发送数据,而且slave超过10秒没有给自己ack消息,那么就直接拒绝客户端的写请求
这样脑裂后的 旧master就不会接受client的新数据 ,也就避免了更多的数据丢失
上面的配置就确保了,如果跟任何一个slave(配置的x为所有从结点的数量)丢了连接,在10秒后发现没有slave给自己ack,那么就拒绝新的写请求
批量删除Redis下特定pattern的keys:
可以使用linux的xargs来做到,如:
/redis-cli
keys
"prefix"
如果是访问特定的数据库,则可以:
/redis-cli
-n
0
keys
"prefix"
Redis是一个开源的使用ANSI
C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。从2010年3月15日起,Redis的开发工作由VMware主持。从2013年5月开始,Redis的开发由Pivotal赞助。
redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted
set
--有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的 *** 作,而且这些 *** 作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改 *** 作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。
redis数据结构
Redis是一种存储key-value的内存型数据库,它的key都是字符串类型,value支持存储5种类型的数据:String(字符串类型)、List(列表类型)、Hash(哈希表类型、即key-value类型)、Set(无序集合类型,元素不可重复)、Zset(有序集合类型,元素不可重复)。
针对这5种数据类型,Redis在底层都是使用的redisObject对象表示的。redisObject有3个重要的属性:type、encoding、ptr。
其中,type表示value的数据类型,也就是我们上面说的5种数据类型(REDIS_STRING、REDIS_LIST、REDIS_HASH、REDIS_SET、REDIS_ZSET);encoding表示value的编码,即底层使用了哪种数据结构;ptr是一个指向保存value的底层数据结构的指针。
其中type和ptr属性不用做过多的解释,一看就知道什么意思,本篇文章主要分析value的encoding编码,也就是不同数据类型的value对应的底层数据结构是什么以及数据结构的原理分析。
Redis(Remote Dictionary Server ),即远程字典服务,是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。
redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的 *** 作,而且这些 *** 作都是原子性的。
在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改 *** 作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。
redis对象 *** 作setTimeout()的用法如下:
setTimeout, expire
设定一个key的活动时间(s)
$redis->setTimeout('x', 3);
有关redis的一系列set *** 作总结如下:
//SET 集合的相关 *** 作
// sadd 集合添加数据 初始化数据
for($i=0; $i < 10 ; $i++){
$redis->sadd("myset",$i+rand(10,99));
}
//srem 删除集合中的一个元素
$bool = $redis->srem("myset",16);
echo (int) $bool;
//sMove 将value元素从名称为srckey的集合移到名称为dstkey的集合
$bool = $redis->sMove("myset", "myset1", 35);
echo $bool;
//smembers 显示集合中的元素
$data = $redis->smembers("myset");
// sIsMember, sContains 名称为key的集合中查找是否有value元素,有ture 没有 false
$bool = $redis->sismember("myset",555);
echo (int)$bool;
//scard ssize集合key元素的个数
echo $redis->scard("myset");
//sInterStore
//求交集并将交集保存到output的集合
//$redis->sInterStore('output', 'key1', 'key2', 'key3')
$redis->sinterstore("output","myset","myset1");
$data = $redis->smembers("output");
echo "<pre>";
print_r($data);
// sUnionStore求并集并将并集保存到output的集合
//$redis->sUnionStore('output', 'key1', 'key2', 'key3');
$redis->sunionstore("uoutput","myset","myset1");
$data = $redis->smembers("uoutput");
echo "<pre>";
print_r($data);
//sort
// 排序,分页等
// 参数
// 'by' => 'some_pattern_',
// 'limit' => array(0, 1),
// 'get' => 'some_other_pattern_' or an array of patterns,
// 'sort' => 'asc' or 'desc',
// 'alpha' => TRUE,
// 'store' => 'external-key'
$data = $redis->sort("myset",array("sort"=>"desc"));
echo "<pre>";
print_r($data);
//ZSET 有序集合的相关 *** 作
//zadd添加元素 zAdd(key, score, member):
for($i=0; $i < 10 ; $i++){
$redis->zadd("zset",$i+rand(10,99),$i+rand(100,999));
}
//zrange zRange(key, start, end,withscores) 返回指定范围的元素
//zRevRange(key, start, end,withscores):返回名称为key的zset(元素已按score从大到小排序)中的index从start到end的所有元素withscores: 是否输出socre的值,默认false,不输出
//zRangeByScore, zRevRangeByScore
//$redis->zRangeByScore(key, star, end, array(withscores, limit ));
//返回名称为key的zset中score >= star且score <= end的所有元素
$data = $redis->zrange("zset",0,3,"withscores"); //end -1 返回所有元素 加withscores withscores做值 使用
echo "<pre>";
print_r($data);
//zDelete, zRem
//zRem(key, member) :删除名称为key的zset中的元素member
$redis->zrem("zset",456);
//zCount
//$redis->zCount(key, star, end);
//返回名称为key的zset中score >= star且score <= end的所有元素的个数
echo $redis->zcount("zset",10,50);
//zRemRangeByScore, zDeleteRangeByScore
$redis->zRemRangeByScore('key', star, end); //zremrangebyscore 删除 socre 大于star score 小于 end d的元素
//删除名称为key的zset中score >= star且score <= end的所有元素,返回删除个数
//zScore 返回名称为key的zset中元素val2的score
echo $redis->zScore("zset", 503);
//zRank, zRevRank zrank("set",value) 返回value 在集合中的位置 索引从0开始
echo $redis->zrank("zset",723);
//zIncrBy
//$redis->zIncrBy('key', increment, 'member');
//如果在名称为key的zset中已经存在元素member,则该元素的score增加increment;否则向集合中添加该元素,其score的值为increment
//zUnion/zInter 就集合的合集和交集
//HASH 哈希的相关 *** 作
//hset 初始化数据
for( $i=0; $i < 10 ;$i++){
$redis->hset("myhash",$i,rand(10,99)+$i);
}
//hget("myhash","key1") 返回哈希 myhash 中键为key1的对应的数值
echo $redis->hget("myhash","0");
//hLen 返回名称为h的hash中元素个数
echo $redis->hlen('myhash');
//hDel 删除名称为h的hash中键为key1的域
echo $redis->hdel("myhash","0");
// hKeys 返回名称为key的hash中所有键
$data = $redis->hkeys('myhash');
//hVals 返回名称为h的hash中所有键对应的value
$data = $redis->hvals("myhash");
//hGetAll 返回名称为h的hash中所有的键(field)及其对应的value
$data = $redis->hgetall("myhash");
echo "<pre>";
print_r($data);
//hExists 判断某个hash的对应的键是否存在
echo $redis->hexists("myhash","0");
//hMset 向名称为key的hash中批量添加元素
$redis->hmset("user:1",array("name1"=>"name1","name2"=>"Joe2"));
//hMGet 返回名称为h的hash中field1,field2对应的value
$data = $redis->hmget('user:1', array('name', 'salary'));
echo "<pre>";
print_r($data);
//Redis 相关 *** 作
//flushDB 清空当前数据库
//flushAll 清空所有数据库
//select 选择数据库
//$redis->select(0);
//move 把key1 移动到数据库2
$redis->move("key1",2);
//rename, renameKey 给key从新命名
//renameNx 与remane类似,但是,如果重新命名的名字已经存在,不会替换成功
//setTimeout, expire 设置key的生命时间
$redis->settimeout("user:1",10);
//expireat 指定一个key的生命时间为一个时间戳
//expireAt key存活到一个unix时间戳时间
$redis->expireat("myhash",time()+ 10);
//dbSize 查看现在数据库有多少key
$count = $redis->dbSize();
//auth 密码认证
$redis->auth('foobared');
//bgrewriteaof 使用aof来进行数据库持久化
$redis->bgrewriteaof();
//slaveof 通过执行 SLAVEOF host port 命令,可以将当前服务器转变为指定服务器的从属服务器(slave server)。
$redis->slaveof('10017', 6379);
//save 将数据同步保存到磁盘
//bgsave 将数据异步保存到磁盘
//lastSave 返回上次成功将数据保存到磁盘的Unix时戳
//info 返回redis的版本信息等详情
echo "<pre>";
print_r($redis->info());
// type 返回key的类型值 1-5
//string: Redis::REDIS_STRING 1
//set: Redis::REDIS_SET 2
//list: Redis::REDIS_LIST 3
//zset: Redis::REDIS_ZSET 4
//hash: Redis::REDIS_HASH 5
//other: Redis::REDIS_NOT_FOUND 6
echo $redis->type("myset"); //2
应用Redis实现数据的读写,同时利用队列处理器定时将数据写入mysql,此种情况存在的问题主要是如何保证mysql与redis的数据同步,二者数据同步的关键在于mysql数据库中主键,方案是在redis启动时去mysql读取所有表键值存入redis中,往redis写数据时,对redis主键自增并进行读取,若mysql更新失败,则需要及时清除缓存及同步redis主键。
String tbname = "login";
//获取mysql表主键值--redis启动时
long id = MySQLgetID(tbname);
//设置redis主键值--redis启动时
redisServiceset(tbname, StringvalueOf(id));
Systemoutprintln(id);
long l = redisServiceincr(tbname);
Systemoutprintln(l);
Login login = new Login;
loginsetId(l);
loginsetName("redis");
redisServicehmset(StringvalueOf(logingetId), login);
boolean b = MySQLinsert("insert into login(id,name) values(" + logingetId + ",'" + logingetName + "')");
/
队列处理器更新mysql失败:
清除缓存数据,同时主键值自减
/
if (!b){
redisServicedelKeyAndDecr(tbname, "Login:"+StringvalueOf(logingetId));
}
Systemoutprintln(redisServiceexists("Login:"+StringvalueOf(logingetId)));
Systemoutprintln(redisServiceget(tbname));
Redis 是一个高性能的key-value数据库, 使用内存作为主存储,数据访问速度非常快,当然它也提供了两种机制支持数据持久化存储比较遗憾的是,Redis项目不直接支持Windows,Windows版项目是由微软开放技术团队建立和维护一个实验性项目(支持32,64位),所以并不适用生产环境,但可在Windows环境下用于开发测试。
1下载安装
猛戳这里就到了开源首页,下载源码包,解压ZIP包后进入msvsbinrelease文件夹有三个文件分别对应32,64位,windows服务三个版本,在这里我们选择64位为例,解压redisbin64zip 到D:redis24,这里主要用到redis-serverexe和redis-cliexe, redis-server用于运行Redis服务器,redis-cli是命令行客户端,通过它连接Redis服务器,并使用Redis命令进行各种 *** 作。
2服务启动配置
复制源码包根目录下redisconf到D:redis24,打开CMD命令提示符,输入以下命令启动redis服务。
启动:
redis-server redisconf
这样redis服务就启动成功了。
配置:
更改redis的配置需要修改redisconf文件,以下是它一些主要的配置注释:
#是否作为守护进程运行 daemonize no #Redis 默认监听端口 port 6379 #客户端闲置多少秒后,断开连接 timeout 300 #日志显示级别 loglevel verbose #指定日志输出的文件名,也可指定到标准输出端口 logfile redislog #设置数据库的数量,默认最大是16,默认连接的数据库是0,可以通过select N 来连接不同的数据库 databases 32 #Dump持久化策略 #当有一条Keys 数据被改变是,900 秒刷新到disk 一次 #save 900 1 #当有10 条Keys 数据被改变时,300 秒刷新到disk 一次 save 300 100 #当有1w 条keys 数据被改变时,60 秒刷新到disk 一次 save 6000 10000 #当dump rdb 数据库的时候是否压缩数据对象 rdbcompression yes #dump 持久化数据保存的文件名 dbfilename dumprdb ########### Replication ##################### #Redis的主从配置,配置slaveof则实例作为从服务器 #slaveof 1921680105 6379 #主服务器连接密码 # masterauth <master-password> ############## 安全性 ########### #设置连接密码 #requirepass <password> ############### LIMITS ############## #最大客户端连接数 # maxclients 128 #最大内存使用率 # maxmemory <bytes> ########## APPEND ONLY MODE ######### #是否开启日志功能 appendonly no # AOF持久化策略 #appendfsync always #appendfsync everysec #appendfsync no ################ VIRTUAL MEMORY ########### #是否开启VM 功能 #vm-enabled no # vm-enabled yes #vm-swap-file logs/redisswap #vm-max-memory 0 #vm-page-size 32 #vm-pages 134217728 #vm-max-threads 4
主从复制
在从服务器配置文件中配置slaveof ,填写服务器IP及端口即可,如果主服务器设置了连接密码,在masterauth后指定密码就行了。
持久化
redis提供了两种持久化文案,Dump持久化和AOF日志文件持久化。 Dump持久化是把内存中的数据完整写入到数据文件,由配置策略触发写入,如果在数据更改后又未达到触发条件而发生故障会造成部分数据丢失。 AOF持久化是日志存储的,是增量的形式,记录每一个数据 *** 作动作,数据恢复时就根据这些日志来生成。
3命令行 *** 作
使用CMD命令提示符,打开redis-cli连接redis服务器 ,也可以使用telnet客户端
# redis-cli -h 服务器 –p 端口 –a 密码
redis-cliexe -h 127001 -p 6379
连接成功后,就可对redis数据增删改查了,如字符串 *** 作:
以下是一些服务器管理常用命令:
info #查看服务器信息 select <dbsize> #选择数据库索引 select 1 flushall #清空全部数据 flushdb #清空当前索引的数据库 slaveof <服务器> <端口> #设置为从服务器 slaveof no one #设置为主服务器 shutdown #关闭服务
以上就是关于redis什么类型数据库全部的内容,包括:redis什么类型数据库、Redis数据丢失问题、redis怎么清除key值前几个字符相同的缓存等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)