欢迎光临
我们一直在努力

redis

快云Redis数据库是一种高性能、高可用的key-value数据库服务。兼容Redis协议标准、提供持久化内存数据存储,满足高读写性能场景及容量需弹性变配的业务需求。 Redis的出现,很大程度补偿了MySQL这类关系型数据库的不足,在部分场合可以对关系数据库起到很好的补充作用

Redis与Memcached有何区别 ?redis和Memcached的区别比较

本篇文章给大家带来的内容是关于Redis与Memcached有何区别 ?redis和Memcached的区别比较,有一定的参考价值,有需要的朋友可以参考一下, memcached和redis,作为近些年最常用的缓存服务器,相信大家对它们再熟悉不过了。前两年还在学校时,我曾经读过它们的主要源码,如今写篇笔记从个人角度简单对比一下它们的实现方式,权当做复习,有理解错误之处,欢迎指正。 文中使用的架构类的图片大多来自于网络,有部分图与最新实现有出入,文中已经指出。 一. 综述 读一个软件的源码,首先要弄懂软件是用作干什么的,那memcached和redis是干啥的?众所周知,数据一般会放在数据库中,但是查询数据会相对比较慢,特别是用户很多时,频繁的查询,需要耗费大量的时间。怎么办呢?数据放在哪里查询快?那肯定是内存中。memcached和redis就是将数据存储在内存中,按照key-value的方式查询,可以大幅度提高效率。所以一般它们都用做缓存服务器,缓存常用的数据,需要查询的时候,直接从它们那儿获取,减少查询数据库的次数,提高查询效率。 二. 服务方式 memcached和redis怎么提供服务呢?它们是独立的进程,需要的话,还可以让他们变成daemon进程,所以我们的用户进程要使用memcached和redis的服务的话,就需要进程间通信了。考虑到用户进程和memcached和redis不一定在同一台机器上,所以还需要支持网络间通信。因此,memcached和redis自己本身就是网络服务器,用户进程通过与他们通过网络来传输数据,显然最简单和最常用的就是使用tcp连接了。另外,memcached和redis都支持udp协议。而且当用户进程和memcached和redis在同一机器时,还可以使用unix域套接字通信。 三. 事件模型 下面开始讲他们具体是怎么实现的了。首先来看一下它们的事件模型。 自从epoll出来以后,几乎所有的网络服务器全都抛弃select和poll,换成了epoll。redis也一样,只不多它还提供对select和poll的支持,可以自己配置使用哪一个,但是一般都是用epoll。另外针对BSD,还支持使用kqueue。而memcached是基于libevent的,不过libevent底层也是使用epoll的,所以可以认为它们都是使用epoll。epoll的特性这里就不介绍了,网上介绍文章很多。 它们都使用epoll来做事件循环,不过redis是单线程的服务器(redis也是多线程的,只不过除了主线程以外,其他线程没有event loop,只是会进行一些后台存储工作),而memcached是多线程的。 redis的事件模型很简单,只有一个event loop,是简单的reactor实现。不过redis事件模型中有一个亮点,我们知道epoll是针对fd的,它返回的就绪事件也是只有fd,redis里面的fd就是服务器与客户端连接的socket的fd,但是处理的时候,需要根据这个fd找到具体的客户端的信息,怎么找呢?通常的处理方式就是用红黑树将fd与客户端信息保存起来,通过fd查找,效率是lgn。不过redis比较特殊,redis的客户端的数量上限可以设置,即可以知道同一时刻,redis所打开的fd的上限,而我们知道,进程的fd在同一时刻是不会重复的(fd只有关闭后才能复用),所以redis使用一个数组,将fd作为数组的下标,数组的元素就是客户端的信息,这样,直接通过fd就能定位客户端信息,查找效率是O(1),还省去了复杂的红黑树的实现(我曾经用c写一个网络服务器,就因为要保持fd和connect对应关系,不想自己写红黑树,然后用了STL里面的set,导致项目变成了c++的,最后项目使用g++编译,这事我不说谁知道?)。显然这种方式只能针对connection数量上限已确定,并且不是太大的网络服务器,像nginx这种http服务器就不适用,nginx就是自己写了红黑树。 而memcached是多线程的,使用master-worker的方式,主线程监听端口,建立连接,然后顺序分配给各个工作线程。每一个从线程都有一个event loop,它们服务不同的客户端。master线程和worker线程之间使用管道通信,每一个工作线程都会创建一个管道,然后保存写端和读端,并且将读端加入event loop,监听可读事件。同时,每个从线程都有一个就绪连接队列,主线程连接连接后,将连接的item放入这个队列,然后往该线程的管道的写端写入一个connect命令,这样event loop中加入的管道读端就会就绪,从线程读取命令,解析命令发现是有连接,然后就会去自己的就绪队列中获取连接,并进行处理。多线程的优势就是可以充分发挥多核的优势,不过编写程序麻烦一点,memcached里面就有各种锁和条件变量来进行线程同步。 四. 内存分配 memcached和redis的核心任务都是在内存中操作数据,内存管理自然是核心的内容。 首先看看他们的内存分配方式。memcached是有自己得内存池的,即预先分配一大块内存,然后接下来分配内存就从内存池中分配,这样可以减少内存分配的次数,提高效率,这也是大部分网络服务器的实现方式,只不过各个内存池的管理方式根据具体情况而不同。而redis没有自己得内存池,而是直接使用时分配,即什么时候需要什么时候分配,内存管理的事交给内核,自己只负责取和释放(redis既是单线程,又没有自己的内存池,是不是感觉实现的太简单了?那是因为它的重点都放在数据库模块了)。不过redis支持使用tcmalloc来替换glibc的malloc,前者是google的产品,比glibc的malloc快。 由于redis没有自己的内存池,所以内存申请和释放的管理就简单很多,直接malloc和free即可,十分方便。而memcached是支持内存池的,所以内存申请是从内存池中获取,而free也是还给内存池,所以需要很多额外的管理操作,实现起来麻烦很多,具体的会在后面memcached的slab机制讲解中分析。 五. 数据库实现 接下来看看他们的最核心内容,各自数据库的实现。 1. memcached数据库实现 memcached只支持key-value,即只能一个key对于一个value。它的数据在内存中也是这样以key-value对的方式存储,它使用slab机制。 首先看memcached是如何存储数据的,即存储key-value对。如下图,每一个key-value对都存储在一个item结构中,包含了相关的属性和key和value的值。 item是保存key-value对的,当item多的时候,怎么查找特定的item是个问题。所以memcached维护了一个hash表,它用于快速查找item。hash表适用开链法(与redis一样)解决键的冲突,每一个hash表的桶里面存储了一个链表,链表节点就是item的指针,如上图中的h_next就是指桶里面的链表的下一个节点。 hash表支持扩容(item的数量是桶的数量的1.5以上时扩容),有一个primary_hashtable,还有一个old_hashtable,其中正常适用primary_hashtable,但是扩容的时候,将old_hashtable = primary_hashtable,然后primary_hashtable设置为新申请的hash表(桶的数量乘以2),然后依次将old_hashtable 里面的数据往新的hash表里面移动,并用一个变量expand_bucket记录以及移动了多少个桶,移动完成后,再free原来的old_hashtable 即可(redis也是有两个hash表,也是移动,不过不是后台线程完成,而是每次移动一个桶)。扩容的操作,专门有一个后台扩容的线程来完成,需要扩容的时候,使用条件变量通知它,完成扩容后,它又考试阻塞等待扩容的条件变量。这样在扩容的时候,查找一个item可能会在primary_hashtable和old_hashtable的任意一个中,需要根据比较它的桶的位置和expand_bucket的大小来比较确定它在哪个表里。 item是从哪里分配的呢?从slab中。如下图,memcached有很多slabclass,它们管理slab,每一个slab其实是trunk的集合,真正的item是在trunk中分配的,一个trunk分配一个item。一个slab中的trunk的大小一样,不同的slab,trunk的大小按比例递增,需要新申请一个item的时候,根据它的大小来选择trunk,规则是比它大的最小的那个trunk。这样,不同大小的item就分配在不同的slab中,归不同的slabclass管理。 这样的缺点是会有部分内存浪费,因为一个trunk可能比item大,如图2,分配100B的item的时候,选择112的trunk,但是会有12B的浪费,这部分内存资源没有使用。 如上图,整个构造就是这样,slabclass管理slab,一个slabclass有一个slab_list,可以管理多个slab,同一个slabclass中的slab的trunk大小都一样。slabclass有一个指针slot,保存了未分配的item已经被free掉的item(不是真的free内存,只是不用了而已),有item不用的时候,就放入slot的头部,这样每次需要在当前slab中分配item的时候,直接取slot取即可,不用管item是未分配过的还是被释放掉的。 然后,每一个slabclass对应一个链表,有head数组和tail数组,它们分别保存了链表的头节点和尾节点。链表中的节点就是改slabclass所分配的item,新分配的放在头部,链表越往后的item,表示它已经很久没有被使用了。当slabclass的内存不足,需要删除一些过期item的时候,就可以从链表的尾部开始删除,没错,这个链表就是为了实现LRU。光靠它还不行,因为链表的查询是O(n)的,所以定位item的时候,使用hash表,这已经有了,所有分配的item已经在hash表中了,所以,hash用于查找item,然后链表有用存储item的最近使用顺序,这也是lru的标准实现方法。 每次需要新分配item的时候,找到slabclass对于的链表,从尾部往前找,看item是否已经过期,过期的话,直接就用这个过期的item当做新的item。没有过期的,则需要从slab中分配trunk,如果slab用完了,则需要往slabclass中添加slab了。 memcached支持设置过期时间,即expire time,但是内部并不定期检查数据是否过期,而是客户进程使用该数据的时候,memcached会检查expire time,如果过期,直接返回错误。这样的优点是,不需要额外的cpu来进行expire time的检查,缺点是有可能过期数据很久不被使用,则一直没有被释放,占用内存。 memcached是多线程的,而且只维护了一个数据库,所以可能有多个客户进程操作同一个数据,这就有可能产生问题。比如,A已经把数据更改了,然后B也更改了改数据,那么A的操作就被覆盖了,而可能A不知道,A任务数据现在的状态时他改完后的那个值,这样就可能产生问题。为了解决这个问题,memcached使用了CAS协议,简单说就是item保存一个64位的unsigned int值,标记数据的版本,每更新一次(数据值有修改),版本号增加,然后每次对数据进行更改操作,需要比对客户进程传来的版本号和服务器这边item的版本号是否一致,一致则可进行更改操作,否则提示脏数据。 以上就是memcached如何实现一个key-value的数据库的介绍。 2. redis数据库实现 首先redis数据库的功能强大一些,因为不像memcached只支持保存字符串,redis支持string, list, set,sorted set,hash table 5种数据结构。例如存储一个人的信息就可以使用hash table,用人的名字做key,然后name super, age 24, 通过key 和 name,就可以取到名字super,或者通过key和age,就可以取到年龄24。这样,当只需要取得age的时候,不需要把人的整个信息取回来,然后从里面找age,直接获取age即可,高效方便。 为了实现这些数据结构,redis定义了抽象的对象redis object,如下图。每一个对象有类型,一共5种:字符串,链表,集合,有序集合,哈希表。 同时,为了提高效率,redis为每种类型准备了多种实现方式,根据特定的场景来选择合适的实现方式,encoding就是表示对象的实现方式的。然后还有记录了对象的lru,即上次被访问的时间,同时在redis 服务器中会记录一个当前的时间(近似值,因为这个时间只是每隔一定时间,服务器进行自动维护的时候才更新),它们两个只差就可以计算出对象多久没有被访问了。 然后redis object中还有引用计数,这是为了共享对象,然后确定对象的删除时间用的。最后使用一个void*指针来指向对象的真正内容。正式由于使用了抽象redis object,使得数据库操作数据时方便很多,全部统一使用redis object对象即可,需要区分对象类型的时候,再根据type来判断。而且正式由于采用了这种面向对象的方法,让redis的代码看起来很像c++代码,其实全是用c写的。 //#define REDIS_STRING 0 // 字符串类型 //#define REDIS_LIST 1 // 链表类型 //#define REDIS_SET 2 // 集合类型(无序的),可以求差集,并集等 //#define REDIS_ZSET 3 // 有序的集合类型 //#define REDIS_HASH 4 // 哈希类型 //#define REDIS_ENCODING_RAW 0 /* Raw representation */ //raw 未加工 //#define REDIS_ENCODING_INT 1 /* Encoded as integer */ //#define REDIS_ENCODING_HT 2...

赞(0)adminadmin阅读(2309)去评论

Redis是什么?Redis有什么好处。什么经常需求-学派吧

本篇文章给大家带来的内容是关于Redis是什么?有哪些应用场景?有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。 一丶Redis介绍 1 Redis是一个开源的 key—value型 单线程 数据库,支持string、list、set、zset和hash类型数据。 默认端口:6379 默认数据库数量:16 二、优点: 1.nosql数据库没有关联关系,数据结构简单,拓展表比较容易 2.nosql读取速度快,对较大数据处理快 三、适用场景: 1.数据高并发的读写 2.海量数据的读写 对扩展性要求高的数据 四、不适场景: 1.需要事务支持(非关系型数据库) 2.基于sql结构化查询储存,关系复杂 五、应用场景 下面这些作者是Redis作者@antirez,他描述了Redis比较适合的一些应用场景,NoSQLFan简单列举在这里,供大家一览: 1.取最新N个数据的操作 比如典型的取你网站的最新文章,通过下面方式,我们可以将最新的5000条评论的ID放在Redis的List集合中,并将超出集合部分从数据库获取 使用LPUSH latest.comments<ID>命令,向list集合中插入数据 插入完成后再用LTRIM latest.comments 0 5000命令使其永远只保存最近5000个ID 然后我们在客户端获取某一页评论时可以用下面的逻辑(伪代码) FUNCTION get_latest_comments(start,num_items): id_list = redis.lrange("latest.comments",start,start+num_items-1) IF id_list.length < num_items id_list = SQL_DB("SELECT ... ORDER BY time LIMIT ...") END RETURN id_list END 如果你还有不同的筛选维度,比如某个分类的最新N条,那么你可以再建一个按此分类的List,只存ID的话,Redis是非常高效的。 2.排行榜应用,取TOP N操作 这个需求与上面需求的不同之处在于,前面操作以时间为权重,这个是以某个条件为权重,比如按顶的次数排序,这时候就需要我们的sorted set出马了,将你要排序的值设置成sorted set的score,将具体的数据设置成相应的value,每次只需要执行一条ZADD命令即可。 3.需要精准设定过期时间的应用 比如你可以把上面说到的sorted set的score值设置成过期时间的时间戳,那么就可以简单地通过过期时间排序,定时清除过期数据了,不仅是清除Redis中的过期数据,你完全可以把Redis里这个过期时间当成是对数据库中数据的索引,用Redis来找出哪些数据需要过期删除,然后再精准地从数据库中删除相应的记录。 4.计数器应用 Redis的命令都是原子性的,你可以轻松地利用INCR,DECR命令来构建计数器系统。 5.Uniq操作,获取某段时间所有数据排重值 这个使用Redis的set数据结构最合适了,只需要不断地将数据往set中扔就行了,set意为集合,所以会自动排重。 6.实时系统,反垃圾系统 通过上面说到的set功能,你可以知道一个终端用户是否进行了某个操作,可以找到其操作的集合并进行分析统计对比等。没有做不到,只有想不到。 7.Pub/Sub构建实时消息系统 Redis的Pub/Sub系统可以构建实时的消息系统,比如很多用Pub/Sub构建的实时聊天系统的例子。 8.构建队列系统 使用list可以构建队列系统,使用sorted set甚至可以构建有优先级的队列系统。 以上就是Redis是什么?有哪些应用场景?的详细内容,更多请关注学派吧其它相关文章!

赞(0)adminadmin阅读(2039)去评论

Redis的事务操作的命令与执行操作教程-mysql教程-学派吧

本篇文章给大家带来的内容是关于Redis的事务操作的命令与执行操作(代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。 序1 本文主要研究一下redis的事务操作 命令 multi与exec 命令行 127.0.0.1:6379> multi OK 127.0.0.1:6379> incr total QUEUED 127.0.0.1:6379> incr len QUEUED 127.0.0.1:6379> exec 1) (integer) 2 2) (integer) 2 127.0.0.1:6379> get total "2" 127.0.0.1:6379> get len "2" lettuce实例 @Test public void testMultiExec(){ RedisClient client = RedisClient.create("redis://192.168.99.100:6379/0"); StatefulRedisConnection<String, String> connection = client.connect(); RedisCommands<String, String> syncCommands = connection.sync(); syncCommands.set("hello","1"); syncCommands.set("world","2"); syncCommands.multi(); syncCommands.incr("hello"); syncCommands.incr("world"); //DefaultTransactionResult[wasRolledBack=false,result=[1, 2, 1, 3, 1]] TransactionResult transactionResult = syncCommands.exec(); System.out.println(transactionResult); System.out.println(syncCommands.get("hello")); System.out.println(syncCommands.get("world")); } 部分执行 命令行 127.0.0.1:6379> multi OK 127.0.0.1:6379> set a hello QUEUED 127.0.0.1:6379> set b world QUEUED 127.0.0.1:6379> incr a QUEUED 127.0.0.1:6379> set c part QUEUED 127.0.0.1:6379> exec 1) OK 2) OK 3) (error) ERR value is not an integer or out of range 4) OK 127.0.0.1:6379> get a "hello" 127.0.0.1:6379> get...

赞(0)adminadmin阅读(2006)去评论
宝塔如何安装配置Redis数据库-

宝塔如何安装配置Redis数据库

前言 今天小编主要来说下如何简单快捷的安装Redis- 1:先搞一台服务器了。这是必不可少的。centos系统 (建议7.2)国内外都可以、建议www.sq9.cn 价格优惠不小 下面开始 2:安装好系统、进行SSH连接、安装宝塔面板、有数据盘的别忘记挂载数据库盘 (centos挂载教程]) 然后进行环境搭配、小编用的是apache+php7.1+mysql5.6 我们是安装过的、你点安装。就自动开始了. 安装好以后 点软件管理。php7.1 设置、安装扩展点击进行安装 、 等待完成就完事了、端口别忘记开放了:6379 阿里云 腾讯等几家公司的 要在安全组里 开放 这只是安装完成了、小编网站用的是wordpress-下次 讲介绍WP配置Redis 让你的网站速度飞起来。

赞(0)adminadmin阅读(7812)去评论
数据库提示Table 'xxx'is marked as crashed and last (automatic) repair failed-

数据库提示Table 'xxx'is marked as crashed and last (automatic) repair failed

学派吧-今天小编碰到一个数据库报错问题、然后开始搜集资料开始解决 把下面的方法发布出来。 Table ‘xxx’is marked as crashed and last (automatic) repair failed。这意味着该表被标记为跌宕了。于是想着修复:repair table arvhives,修复却失败了。   只好通过mysql命令行来执行了。   1)service mysqld stop 停止mysql服务;   2)cd /var/local/mysql/tbl 切换到该表目录下(注意:不切换过来会总提示myisamchk一些错误导致失败);   3)myisamchk -r xxx.MYI (如果还是提示错误,就多加一个参数-f 强制进行。) [root@localhost tjinfo]# myisamchk -r dede_archives.MYI - recovering (with sort) MyISAM-table 'dede_archives.MYI' Data records: 1781 - Fixing index 1 - Fixing index 2 - Fixing index 3 - Fixing index 4 最后查看,成功! 注意:虽然这样成功了,但是当你再次添加文章的时候,又会出现这样的问题,所以长久的解决办法如下: 把服务器上的数据导入到本地,然后在本地用myisamchk -r -f *.MYI修复了下,然后导回去。 如有不懂。欢迎加学派吧 站长群 右上角

赞(0)adminadmin阅读(3161)去评论
Redis数据库有什么好处,怎么使用-

Redis数据库有什么好处,怎么使用

学派吧- 今天有个用户使用了Redis ,他是把数据库写入到了内存,那速度是叫一个快。但是学派吧也查了相关的材料。发现。站长朋友布置起来有点难度 今天我们不说他如何使用。只说说他的好处及弊端。 1. 什么是Redis Redis是由意大利人Salvatore Sanfilippo(网名:antirez)开发的一款内存高速缓存数据库。Redis全称为:Remote Dictionary Server(远程数据服务),该软件使用C语言编写,Redis是一个key-value存储系统,它支持丰富的数据类型,如:string、list、set、zset(sorted set)、hash。 2. Redis特点 Redis以内存作为数据存储介质,所以读写数据的效率极高,远远超过数据库。以设置和获取一个256字节字符串为例,它的读取速度可高达110000次/s,写速度高达81000次/s。 Redis跟memcache不同的是,储存在Redis中的数据是持久化的,断电或重启后,数据也不会丢失。因为Redis的存储分为内存存储、磁盘存储和log文件三部分,重启后,Redis可以从磁盘重新将数据加载到内存中,这些可以通过配置文件对其进行配置,正因为这样,Redis才能实现持久化。 Redis支持主从模式,可以配置集群,这样更利于支撑起大型的项目,这也是Redis的一大亮点。 3. Redis应用场景,它能做什么 众多语言都支持Redis,因为Redis交换数据快,所以在服务器中常用来存储一些需要频繁调取的数据,这样可以大大节省系统直接读取磁盘来获得数据的I/O开销,更重要的是可以极大提升速度。 拿大型网站来举个例子,比如a网站首页一天有100万人访问,其中有一个板块为推荐新闻。要是直接从数据库查询,那么一天就要多消耗100万次数据库请求。上面已经说过,Redis支持丰富的数据类型,所以这完全可以用Redis来完成,将这种热点数据存到Redis(内存)中,要用的时候,直接从内存取,极大的提高了速度和节约了服务器的开销。 总之,Redis的应用是非常广泛的,而且极有价值,真是服务器中的一件利器,所以从现在开始,我们就来一步步学好它。 弊端是什么呢: 分析:大家用redis这么久,这个问题是必须要了解的,基本上使用redis都会碰到一些问题,常见的也就几个。 回答:主要是四个问题 (一)缓存和数据库双写一致性问题 (二)缓存雪崩问题 (三)缓存击穿问题 (四)缓存的并发竞争问题 这四个问题,我个人是觉得在项目中,比较常遇见的,具体解决方案,后文给出 欢迎大家关注学派吧、关注我们QQ群:右上角加入

赞(0)adminadmin阅读(3883)去评论

更好的服务器推荐选择

本站主要用于阿里云、腾讯云、华为云服务器活动的推荐及优惠购买方式、并搜集服务器运维的日常解决方案!

联系我们联系我们

登录

找回密码

注册