make
14.编译完成之后,将redis安装到指定目录m_redis version=5.0.3">热门标签热门文章- 1探索AI人才培养新范式,合合信息与同济大学软件学院签署产教融合人才培养协议
- 2数据结构——链表(C语言实现)_严蔚敏 数据结构 c语言代码 线性链表
- 3动态规划课堂5-----子序列问题(动态规划 + 哈希表)_子序列:是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺
- 4基于springboot实现秒杀系统项目【项目源码+论文说明】计算机毕业设计_基于springbiit的房产销售系统论文
- 5【已拿offer】最新AI产品经理大厂面经(含百度&腾讯&科大讯飞&商汤&蚂蚁金服)_商汤pk科大讯飞
- 6数字抽取滤波(一)
- 7基于小程序和SSM实现智能推荐的电影推荐_ssm框架 + 推荐算法 具体实现
- 8unity3D 插件plugins_managed plugins
- 9Linux安装Mysql详细教程(两种安装方法)_linux 安装mysql
- 10swift 3d v6.0汉化中文版_swift 3d软件
当前位置: article > 正文 Centos7下安装、配置Redis5.0.3以及redis详解_redis version=5.0.3
作者:正经夜光杯 | 2024-07-15 00:10:36 赞
踩
redis version=5.0.3
一、安装
1.官网下载Redis
Redis官网(有时候需要翻墙)
2.上传下载好的包到Centos上并解压(本人上传到了usr/local目录下)
3.进入redis-5.0.3目录里,执行编译命令
- <span style="color:#000000"><code>make
- </code></span>
- 1
4.编译完成之后,将redis安装到指定目录
- <span style="color:#000000"><code>make PREFIX=/usr/local/redis install
- </code></span>
- 1
5.此时/usr/local/redis下生成了一个bin目录
至此安装完成;
二、启动
1.启动方式一
前台启动,不推荐使用,进入/usr/local/redis/bin里执行启动命令(默认端口号:6379)
- <span style="color:#000000"><code>./redis-server
- </code></span>
- 1
2.启动方式二
后台启动,推荐使用,将redis-5.0.3目录下的redis.conf文件复制到 /usr/local/redis/bin 下
- <span style="color:#000000"><code>cp redis.conf /usr/local/redis/bin/
- </code></span>
- 1
修改redis.conf 设置为后台启动,将daemonize no改为daemonize yes即可(redis.conf文件内容较多,全局搜索:/daemonize 然后回车,再不断敲N即可)
启动Redis:进入/usr/local/redis/bin目录,执行下边命令
- <span style="color:#000000"><code>./redis-server /usr/local/redis/bin/redis.conf
- 由于redis.conf与redis-serve在同一级目录,所以执行下边命令即可
- ./redis-server redis.conf
- </code></span>
- 1
- 2
- 3
关闭Redis:进入/usr/local/redis/bin目录,执行下边命令
- <span style="color:#000000"><code>./redis-cli shutdown
- </code></span>
- 1
3.查看redis进程:
- <span style="color:#000000"><code>ps -ef | grep -i redis
- </code></span>
- 1
看到如下信息:
- <span style="color:#000000"><code>root 1218 1 0 12:04 ? 00:00:00 /usr/local/redis/bin/redis-server 127.0.0.1:6379
- root 1257 1186 0 12:11 pts/0 00:00:00 grep --color=auto -i redis
- </code></span>
- 1
- 2
可以杀死Redis进程:
- <span style="color:#000000"><code>kill -9 1218
- </code></span>
- 1
4.客户端操作
进入 /usr/local/redis/bin/目录:
- <span style="color:#000000"><code>./redis-cli
- </code></span>
- 1
此时就可以设置值并取值了:
三、配置
1.允许远程连接Redis
redis 默认只允许自己的电脑(127.0.0.1)连接。如果想要其他电脑进行远程连接,将配置文件 redis.conf 中的 bind 127.0.0.1 注释掉(之前没注释,需要改为将其注释掉,默认只能连接本地)。
找到配置文件redis.conf中protected mode,默认protected mode yes,需要将其改为protected mode no
此时,远程就可以连接Redis了;
redis自带客户端连接远程redis服务端:
- <span style="color:#000000"><code># 进入到redis安装目录的bin目录里,执行如下命令
- ./redis-cli -h 192.168.237.129 -p 6379
- </code></span>
- 1
- 2
连接上以后就可以向服务端发送命令了,Redis提供了PING命令来测试客户端与Redis的连接是否正常,如果连接正常会收到回复PONG
使用set和get可以向redis设置数据、获取数据:
del删除指定key的内容:
- <span style="color:#000000"><code>del name
- </code></span>
- 1
查看当前库中所有的key值:
- <span style="color:#000000"><code>key *
- </code></span>
- 1
四、SpringBoot连接并操作Redis
1、引入依赖
- <span style="color:#000000"><code> <!--Redis依赖-->
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-data-redis</artifactId>
- </dependency>
- </code></span>
- 1
- 2
- 3
- 4
- 5
2、配置文件里配置redis
- <span style="color:#000000"><code>spring:
- application:
- name: order-service
- redis:
- database: 0
- #远程redis地址
- host: 192.168.237.128
- #redis默认端口就是6379
- port: 6379
- timeout: 2000
- </code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
3、使用RedisTemplate操作Redis
- <span style="color:#000000"><code class="language-java"><span style="color:#999999">@Autowired</span>
- <span style="color:#c678dd">private</span> StringRedisTemplate redisTemplate<span style="color:#999999">;</span>
- <span style="color:#999999">.</span><span style="color:#999999">.</span><span style="color:#999999">.</span><span style="color:#999999">.</span><span style="color:#999999">.</span><span style="color:#999999">.</span><span style="color:#999999">.</span><span style="color:#999999">.</span><span style="color:#999999">.</span><span style="color:#999999">.</span><span style="color:#999999">.</span><span style="color:#999999">.</span><span style="color:#999999">.</span><span style="color:#999999">.</span><span style="color:#999999">.</span><span style="color:#999999">.</span><span style="color:#999999">.</span><span style="color:#999999">.</span><span style="color:#999999">.</span><span style="color:#999999">.</span><span style="color:#999999">.</span><span style="color:#999999">.</span><span style="color:#999999">.</span><span style="color:#999999">.</span><span style="color:#999999">.</span><span style="color:#999999">.</span><span style="color:#999999">.</span><span style="color:#999999">.</span><span style="color:#999999">.</span><span style="color:#999999">.</span><span style="color:#999999">.</span><span style="color:#999999">.</span><span style="color:#999999">.</span><span style="color:#999999">.</span><span style="color:#999999">.</span><span style="color:#999999">.</span><span style="color:#999999">.</span><span style="color:#999999">.</span><span style="color:#999999">.</span><span style="color:#999999">.</span><span style="color:#999999">.</span><span style="color:#999999">.</span><span style="color:#999999">.</span>
- <span style="color:#c678dd">private</span> Object <span style="color:#61aeee">saveOrderFail</span><span style="color:#999999">(</span><span style="color:#c678dd">int</span> userId<span style="color:#999999">,</span> <span style="color:#c678dd">int</span> productId<span style="color:#999999">,</span> HttpServletRequest request<span style="color:#999999">)</span><span style="color:#999999">{</span>
- <span style="color:#5c6370">//监控报警 start</span>
- String saveOrderKey<span style="color:#669900">=</span><span style="color:#669900">"save-order"</span><span style="color:#999999">;</span>
- String sendValue <span style="color:#669900">=</span> redisTemplate<span style="color:#999999">.</span><span style="color:#61aeee">opsForValue</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">.</span><span style="color:#61aeee">get</span><span style="color:#999999">(</span>saveOrderKey<span style="color:#999999">)</span><span style="color:#999999">;</span>
- String ip<span style="color:#669900">=</span>request<span style="color:#999999">.</span><span style="color:#61aeee">getRemoteAddr</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
- <span style="color:#5c6370">//注意,这里需要异步,不能同步,不然此处阻塞的话(发短息耗时的话)不会继续向下走</span>
- <span style="color:#c678dd">new</span> Thread<span style="color:#999999">(</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#669900">-</span><span style="color:#669900">></span><span style="color:#999999">{</span>
- <span style="color:#c678dd">if</span><span style="color:#999999">(</span>StringUtils<span style="color:#999999">.</span><span style="color:#61aeee">isBlank</span><span style="color:#999999">(</span>sendValue<span style="color:#999999">)</span><span style="color:#999999">)</span><span style="color:#999999">{</span>
- System<span style="color:#999999">.</span>out<span style="color:#999999">.</span><span style="color:#61aeee">println</span><span style="color:#999999">(</span><span style="color:#669900">"调用发短信接口去发送短信;用户下单失败,请马上处理;"</span><span style="color:#669900">+</span>ip<span style="color:#999999">)</span><span style="color:#999999">;</span>
- <span style="color:#5c6370">//此时调用发短信接口去发送短信,略过</span>
-
- <span style="color:#5c6370">/**
- * 在Redis里放入数据,防止一直不停的发短信
- * 间隔时间20秒(正常比这个数据久,这里为了测试先设置20秒)
- */</span>
- redisTemplate<span style="color:#999999">.</span><span style="color:#61aeee">opsForValue</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">.</span><span style="color:#61aeee">set</span><span style="color:#999999">(</span>saveOrderKey<span style="color:#999999">,</span><span style="color:#669900">"save-order-fail"</span><span style="color:#999999">,</span><span style="color:#98c379">20</span><span style="color:#999999">,</span> TimeUnit<span style="color:#999999">.</span>SECONDS<span style="color:#999999">)</span><span style="color:#999999">;</span>
- <span style="color:#999999">}</span><span style="color:#c678dd">else</span><span style="color:#999999">{</span>
- System<span style="color:#999999">.</span>out<span style="color:#999999">.</span><span style="color:#61aeee">println</span><span style="color:#999999">(</span><span style="color:#669900">"已经发生过短信了,20秒内不要发了"</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
- <span style="color:#999999">}</span>
- <span style="color:#999999">}</span><span style="color:#999999">)</span><span style="color:#999999">.</span><span style="color:#61aeee">start</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
-
- <span style="color:#5c6370">//监控报警 end</span>
- Map<span style="color:#61aeee"><span style="color:#999999"><</span>String<span style="color:#999999">,</span>Object<span style="color:#999999">></span></span> msg<span style="color:#669900">=</span><span style="color:#c678dd">new</span> HashMap<span style="color:#669900"><</span><span style="color:#669900">></span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
- msg<span style="color:#999999">.</span><span style="color:#61aeee">put</span><span style="color:#999999">(</span><span style="color:#669900">"code"</span><span style="color:#999999">,</span><span style="color:#669900">-</span><span style="color:#98c379">1</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
- msg<span style="color:#999999">.</span><span style="color:#61aeee">put</span><span style="color:#999999">(</span><span style="color:#669900">"msg"</span><span style="color:#999999">,</span><span style="color:#669900">"抢购人数太多,稍后重试"</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
- <span style="color:#c678dd">return</span> msg<span style="color:#999999">;</span>
- <span style="color:#999999">}</span>
-
- </code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
使用RedisTemplate从redis里取数据
- <span style="color:#000000"><code class="language-java"><span style="color:#5c6370">//从缓存里取数据</span>
- <span style="color:#c678dd">public</span> Article <span style="color:#61aeee">findById</span><span style="color:#999999">(</span>String id<span style="color:#999999">)</span> <span style="color:#999999">{</span>
- <span style="color:#5c6370">//从缓存中提取</span>
- Article article<span style="color:#669900">=</span><span style="color:#999999">(</span>Article<span style="color:#999999">)</span>redisTemplate<span style="color:#999999">.</span><span style="color:#61aeee">opsForValue</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">.</span><span style="color:#61aeee">get</span><span style="color:#999999">(</span><span style="color:#669900">"article_"</span><span style="color:#669900">+</span>id<span style="color:#999999">)</span><span style="color:#999999">;</span>
- <span style="color:#5c6370">// 如果缓存没有则到数据库查询并放入缓存</span>
- <span style="color:#c678dd">if</span><span style="color:#999999">(</span>article<span style="color:#669900">==</span>null<span style="color:#999999">)</span> <span style="color:#999999">{</span>
- article <span style="color:#669900">=</span> articleDao<span style="color:#999999">.</span><span style="color:#61aeee">findById</span><span style="color:#999999">(</span>id<span style="color:#999999">)</span><span style="color:#999999">.</span><span style="color:#61aeee">get</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
- redisTemplate<span style="color:#999999">.</span><span style="color:#61aeee">opsForValue</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">.</span><span style="color:#61aeee">set</span><span style="color:#999999">(</span><span style="color:#669900">"article_"</span> <span style="color:#669900">+</span> id<span style="color:#999999">,</span> article<span style="color:#999999">)</span><span style="color:#999999">;</span>
- <span style="color:#999999">}</span>
- <span style="color:#c678dd">return</span> article<span style="color:#999999">;</span>
- <span style="color:#999999">}</span>
- </code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
修改或删除数据库时使用RedisTemplate清空缓存
- <span style="color:#000000"><code class="language-java"><span style="color:#5c6370">/**
- * 修改
- * @param article
- */</span>
- <span style="color:#c678dd">public</span> <span style="color:#c678dd">void</span> <span style="color:#61aeee">update</span><span style="color:#999999">(</span>Article article<span style="color:#999999">)</span> <span style="color:#999999">{</span>
- redisTemplate<span style="color:#999999">.</span><span style="color:#61aeee">delete</span><span style="color:#999999">(</span> <span style="color:#669900">"article_"</span> <span style="color:#669900">+</span> article<span style="color:#999999">.</span><span style="color:#61aeee">getId</span><span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#999999">)</span><span style="color:#999999">;</span><span style="color:#5c6370">//删除缓存</span>
- articleDao<span style="color:#999999">.</span><span style="color:#61aeee">save</span><span style="color:#999999">(</span>article<span style="color:#999999">)</span><span style="color:#999999">;</span>
- <span style="color:#999999">}</span>
- <span style="color:#5c6370">/**
- * 删除
- * @param id
- */</span>
- <span style="color:#c678dd">public</span> <span style="color:#c678dd">void</span> <span style="color:#61aeee">deleteById</span><span style="color:#999999">(</span>String id<span style="color:#999999">)</span> <span style="color:#999999">{</span>
- redisTemplate<span style="color:#999999">.</span><span style="color:#61aeee">delete</span><span style="color:#999999">(</span> <span style="color:#669900">"article_"</span> <span style="color:#669900">+</span> id <span style="color:#999999">)</span><span style="color:#999999">;</span><span style="color:#5c6370">//删除缓存</span>
- articleDao<span style="color:#999999">.</span><span style="color:#61aeee">deleteById</span><span style="color:#999999">(</span>id<span style="color:#999999">)</span><span style="color:#999999">;</span>
- <span style="color:#999999">}</span>
- </code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
使用RedisTemplate设置缓存过期时间
- <span style="color:#000000"><code class="language-java"><span style="color:#5c6370">//过期时间为一天</span>
- redisTemplate<span style="color:#999999">.</span><span style="color:#61aeee">opsForValue</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">.</span><span style="color:#61aeee">set</span><span style="color:#999999">(</span><span style="color:#669900">"article_"</span> <span style="color:#669900">+</span> id<span style="color:#999999">,</span> article<span style="color:#999999">,</span><span style="color:#98c379">1</span><span style="color:#999999">,</span>
- TimeUnit<span style="color:#999999">.</span>DAYS<span style="color:#999999">)</span><span style="color:#999999">;</span>
-
- <span style="color:#5c6370">//过期时间为10秒</span>
- redisTemplate<span style="color:#999999">.</span><span style="color:#61aeee">opsForValue</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">.</span><span style="color:#61aeee">set</span><span style="color:#999999">(</span><span style="color:#669900">"article_"</span> <span style="color:#669900">+</span> id<span style="color:#999999">,</span> article<span style="color:#999999">,</span><span style="color:#98c379">10</span><span style="color:#999999">,</span>
- TimeUnit<span style="color:#999999">.</span>SECONDS<span style="color:#999999">)</span><span style="color:#999999">;</span>
- </code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
五、centos6安装配置redis
redis安装和配置
1.安装
-
下载安装包
官网下载
-
解压
- <span style="color:#000000"><code class="language-shell"> <span style="color:#61aeee">tar</span> -xvf redis-4.0.9.tar.gz
- </code></span>
- 1
- 编译安装
- <span style="color:#000000"><code class="language-shell"> <span style="color:#61aeee">mv</span> redis-4.0.9 redis
- <span style="color:#61aeee">cd</span> redis
- <span style="color:#61aeee">make</span> <span style="color:#669900">&&</span> <span style="color:#61aeee">make</span> <span style="color:#61aeee">install</span>
- </code></span>
- 1
- 2
- 3
2.配置
修改安装目录下的redis.conf文件
- <span style="color:#000000"><code class="language-shell">vim redis.conf
- </code></span>
- 1
修改以下配置:
- <span style="color:#000000"><code class="language-shell"><span style="color:#5c6370">#bind 127.0.0.1 # 将这行代码注释,监听所有的ip地址,外网可以访问</span>
- protected-mode no <span style="color:#5c6370"># 把yes改成no,允许外网访问</span>
- daemonize <span style="color:#61aeee">yes</span> <span style="color:#5c6370"># 把no改成yes,后台运行</span>
- </code></span>
- 1
- 2
- 3
3.启动或停止
redis提供了服务端命令和客户端命令:
- redis-server 服务端命令,可以包含以下参数:
start 启动
stop 停止 - redis-cli 客户端控制台,包含参数:
-h xxx 指定服务端地址,缺省值是127.0.0.1
-p xxx 指定服务端端口,缺省值是6379
4.设置开机启动
- 输入命令,新建文件
- <span style="color:#000000"><code class="language-sh">vim /etc/init.d/redis
- </code></span>
- 1
输入下面内容:
- <span style="color:#000000"><code class="language-sh">#!/bin/sh
- # chkconfig: 2345 90 10
- # description: Redis is a persistent key-value database
- PATH=/usr/local/bin:/sbin:/usr/bin:/bin
-
- REDISPORT=6379
- EXEC=/usr/local/bin/redis-server
- REDIS_CLI=/usr/local/bin/redis-cli
-
- PIDFILE=/var/run/redis.pid
-
- CONF="/home/leyou/redis/redis.conf"
-
- case "$1" in
- start)
- if [ -f $PIDFILE ]
- then
- echo "$PIDFILE exists, process is already running or crashed"
- else
- echo "Starting Redis server..."
- $EXEC $CONF
- fi
- if [ "$?"="0" ]
- then
- echo "Redis is running..."
- fi
- ;;
- stop)
- if [ ! -f $PIDFILE ]
- then
- echo "$PIDFILE does not exist, process is not running"
- else
- PID=$(cat $PIDFILE)
- echo "Stopping ..."
- $REDIS_CLI -p $REDISPORT SHUTDOWN
- while [ -x ${PIDFILE} ]
- do
- echo "Waiting for Redis to shutdown ..."
- sleep 1
- done
- echo "Redis stopped"
- fi
- ;;
- restart|force-reload)
- ${0} stop
- ${0} start
- ;;
- *)
- echo "Usage: /etc/init.d/redis {start|stop|restart|force-reload}" >&2
- exit 1
- esac
-
- </code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
然后保存退出
注意:以下信息需要根据安装目录进行调整:
EXEC=/usr/local/bin/redis-server # 执行脚本的地址
REDIS_CLI=/usr/local/bin/redis-cli # 客户端执行脚本的地址
PIDFILE=/var/run/redis.pid # 进程id文件地址
CONF="/usr/local/src/redis-3.0.2/redis.conf" #配置文件地址
2)设置权限
- <span style="color:#000000"><code class="language-sh">chmod 755 /etc/init.d/redis
- </code></span>
- 1
3)启动测试
- <span style="color:#000000"><code class="language-sh">/etc/init.d/redis start
- </code></span>
- 1
启动成功会提示如下信息:
- <span style="color:#000000"><code>Starting Redis server...
- Redis is running...
- </code></span>
- 1
- 2
4)设置开机自启动
- <span style="color:#000000"><code class="language-sh">chkconfig --add /etc/init.d/redis
- chkconfig redis on
- </code></span>
- 1
- 2
六、redis多数据库
启动多个redis进程
- 创建多个redis目录,以端口号命名,比如:创建6379、6380两个目录,将redis的安装文件bin和conf拷贝至这两个目录。
- 修改6379目录下的redis.conf设置端口号为6379
修改6380目录下的redis.conf设置端口号为6380 - 启动6379和6380目录下的redis-server程序:
- <span style="color:#000000"><code>cd 6379
- ./redis-server . /redis.conf
- cd 6380
- ./redis-server . /redis.conf
- </code></span>
- 1
- 2
- 3
- 4
此时,查看redis进程,发现有两个redis进程在运行
redis实例
一个redis进程就是一个redis实例,一台服务器可以同时有多个redis实例,不同的redis实例提供不同的服务端口对外提供服务,每个redis实例之间互相影响。每个redis实例都包括自己的数据库,数据库中可以存储自己的数据。
多数据库测试
一个Redis实例可以包括多个数据库,客户端可以指定连接某个redis实例的哪个数据库,就好比一个mysql中创建多个数据库,客户端连接时指定连接哪个数据库。
一个redis实例最多可提供16个数据库,下标从0到15,客户端默认连接第0号数据库,也可以通过select选择连接哪个数据库,如下连接1号库:
在1号库中查询上节设置的数据,结果查询不到:
重新选择第0号数据库,查询数据:
如果选择一个不存在的数据库则会报错:
注意:redis不支持修改数据库的名称,只能通过select 0、select 1…选择数据库
注意的问题
在0号数据库存储数据,在1号数据库执行清空数据命令却把0号数据库的数据给清空了:
建议:不同的应用系统要使用不同的redis实例,而不是使用同一个redis实例下的不同数据库。
七、Jedis
7.1、jedis介绍
Redis不仅是使用命令来操作,现在基本上主流的语言都有客户端支持,比如java、C、C#、C++、php、Node.js、Go等。
在官方网站里列一些Java的客户端,有Jedis、Redisson、Jredis、JDBC-Redis等,其中官方推荐使用Jedis和Redisson。 在企业中用的最多的就是Jedis,下面我们就重点学习下Jedis。 Jedis同样也是托管在github上,地址:https://github.com/xetorthio/jedis
7.2 通过jedis连接redis单机
添加依赖
- <span style="color:#000000"><code><dependency>
- <groupId>redis.clients</groupId>
- <artifactId>jedis</artifactId>
- <version>2.7.0</version>
- </dependency>
- </code></span>
- 1
- 2
- 3
- 4
- 5
7.2.1 单实例连接
通过创建单实例jedis对象连接redis服务,如下代码
- <span style="color:#000000"><code class="language-java"> <span style="color:#5c6370">// 单实例连接redis</span>
- <span style="color:#999999">@Test</span>
- <span style="color:#c678dd">public</span> <span style="color:#c678dd">void</span> <span style="color:#61aeee">testJedisSingle</span><span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#999999">{</span>
- Jedis jedis <span style="color:#669900">=</span> <span style="color:#c678dd">new</span> Jedis<span style="color:#999999">(</span><span style="color:#669900">"192.168.237.129"</span><span style="color:#999999">,</span> <span style="color:#98c379">6379</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
- jedis<span style="color:#999999">.</span><span style="color:#61aeee">set</span><span style="color:#999999">(</span><span style="color:#669900">"name"</span><span style="color:#999999">,</span> <span style="color:#669900">"bar"</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
- String name <span style="color:#669900">=</span> jedis<span style="color:#999999">.</span><span style="color:#61aeee">get</span><span style="color:#999999">(</span><span style="color:#669900">"name"</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
- System<span style="color:#999999">.</span>out<span style="color:#999999">.</span><span style="color:#61aeee">println</span><span style="color:#999999">(</span>name<span style="color:#999999">)</span><span style="color:#999999">;</span>
- jedis<span style="color:#999999">.</span><span style="color:#61aeee">close</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
- <span style="color:#999999">}</span>
- </code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
连接超时解决
由于linux防火墙默认开启,redis的服务端口6379并不在开放规则之内,所有需要将此端口开放访问或者关闭防火墙。关闭防火墙命令:
- <span style="color:#000000"><code>sevice iptables stop
- </code></span>
- 1
如果是修改防火墙规则,可以修改:/etc/sysconfig/iptables文件
7.2.2 使用连接池连接
通过单实例连接redis不能对redis连接进行共享,可以使用连接池对redis连接进行共享,提高资源利用率,使用jedisPool连接redis服务,如下代码:
- <span style="color:#000000"><code class="language-java"> <span style="color:#999999">@Test</span>
- <span style="color:#c678dd">public</span> <span style="color:#c678dd">void</span> <span style="color:#61aeee">pool</span><span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#999999">{</span>
- JedisPoolConfig config <span style="color:#669900">=</span> <span style="color:#c678dd">new</span> JedisPoolConfig<span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
- <span style="color:#5c6370">//最大连接数</span>
- config<span style="color:#999999">.</span><span style="color:#61aeee">setMaxTotal</span><span style="color:#999999">(</span><span style="color:#98c379">30</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
- <span style="color:#5c6370">//最大连接空闲数</span>
- config<span style="color:#999999">.</span><span style="color:#61aeee">setMaxIdle</span><span style="color:#999999">(</span><span style="color:#98c379">2</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
-
- JedisPool pool <span style="color:#669900">=</span> <span style="color:#c678dd">new</span> JedisPool<span style="color:#999999">(</span>config<span style="color:#999999">,</span> <span style="color:#669900">"192.168.237.129"</span><span style="color:#999999">,</span> <span style="color:#98c379">6379</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
- Jedis jedis <span style="color:#669900">=</span> null<span style="color:#999999">;</span>
-
- <span style="color:#c678dd">try</span> <span style="color:#999999">{</span>
- jedis <span style="color:#669900">=</span> pool<span style="color:#999999">.</span><span style="color:#61aeee">getResource</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
-
- jedis<span style="color:#999999">.</span><span style="color:#61aeee">set</span><span style="color:#999999">(</span><span style="color:#669900">"name"</span><span style="color:#999999">,</span> <span style="color:#669900">"lisi"</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
- String name <span style="color:#669900">=</span> jedis<span style="color:#999999">.</span><span style="color:#61aeee">get</span><span style="color:#999999">(</span><span style="color:#669900">"name"</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
- System<span style="color:#999999">.</span>out<span style="color:#999999">.</span><span style="color:#61aeee">println</span><span style="color:#999999">(</span>name<span style="color:#999999">)</span><span style="color:#999999">;</span>
- <span style="color:#999999">}</span><span style="color:#c678dd">catch</span><span style="color:#999999">(</span>Exception ex<span style="color:#999999">)</span><span style="color:#999999">{</span>
- ex<span style="color:#999999">.</span><span style="color:#61aeee">printStackTrace</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
- <span style="color:#999999">}</span><span style="color:#c678dd">finally</span><span style="color:#999999">{</span>
- <span style="color:#c678dd">if</span><span style="color:#999999">(</span>jedis <span style="color:#669900">!=</span> null<span style="color:#999999">)</span><span style="color:#999999">{</span>
- <span style="color:#5c6370">//关闭连接</span>
- jedis<span style="color:#999999">.</span><span style="color:#61aeee">close</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
- <span style="color:#999999">}</span>
- <span style="color:#999999">}</span>
- <span style="color:#999999">}</span>
- </code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
7.2.3、jedis与spring整合
配置spring配置文件applicationContext.xml
- <span style="color:#000000"><code><?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
- xmlns:context="http://www.springframework.org/schema/context"
- xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
- http://www.springframework.org/schema/mvc
- http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
- http://www.springframework.org/schema/context
- http://www.springframework.org/schema/context/spring-context-3.2.xsd
- http://www.springframework.org/schema/aop
- http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
- http://www.springframework.org/schema/tx
- http://www.springframework.org/schema/tx/spring-tx-3.2.xsd ">
-
- <!-- 连接池配置 -->
- <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
- <!-- 最大连接数 -->
- <property name="maxTotal" value="30" />
- <!-- 最大空闲连接数 -->
- <property name="maxIdle" value="10" />
- <!-- 每次释放连接的最大数目 -->
- <property name="numTestsPerEvictionRun" value="1024" />
- <!-- 释放连接的扫描间隔(毫秒) -->
- <property name="timeBetweenEvictionRunsMillis" value="30000" />
- <!-- 连接最小空闲时间 -->
- <property name="minEvictableIdleTimeMillis" value="1800000" />
- <!-- 连接空闲多久后释放, 当空闲时间>该值 且 空闲连接>最大空闲连接数 时直接释放 -->
- <property name="softMinEvictableIdleTimeMillis" value="10000" />
- <!-- 获取连接时的最大等待毫秒数,小于零:阻塞不确定的时间,默认-1 -->
- <property name="maxWaitMillis" value="1500" />
- <!-- 在获取连接的时候检查有效性, 默认false -->
- <property name="testOnBorrow" value="true" />
- <!-- 在空闲时检查有效性, 默认false -->
- <property name="testWhileIdle" value="true" />
- <!-- 连接耗尽时是否阻塞, false报异常,ture阻塞直到超时, 默认true -->
- <property name="blockWhenExhausted" value="false" />
- </bean>
-
- <!-- redis单机 通过连接池 -->
- <bean id="jedisPool" class="redis.clients.jedis.JedisPool" destroy-method="close">
- <constructor-arg name="poolConfig" ref="jedisPoolConfig"/>
- <constructor-arg name="host" value="192.168.25.145"/>
- <constructor-arg name="port" value="6379"/>
- </bean>
- </beans>
- </code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
测试代码:
- <span style="color:#000000"><code class="language-java"> <span style="color:#c678dd">private</span> ApplicationContext applicationContext<span style="color:#999999">;</span>
-
- <span style="color:#999999">@Before</span>
- <span style="color:#c678dd">public</span> <span style="color:#c678dd">void</span> <span style="color:#61aeee">init</span><span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#999999">{</span>
- applicationContext <span style="color:#669900">=</span> <span style="color:#c678dd">new</span> ClassPathXmlApplicationContext<span style="color:#999999">(</span>
- <span style="color:#669900">"classpath:applicationContext.xml"</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
- <span style="color:#999999">}</span>
-
- <span style="color:#999999">@Test</span>
- <span style="color:#c678dd">public</span> <span style="color:#c678dd">void</span> <span style="color:#61aeee">testJedisPool</span><span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#999999">{</span>
- JedisPool pool <span style="color:#669900">=</span> <span style="color:#999999">(</span>JedisPool<span style="color:#999999">)</span> applicationContext<span style="color:#999999">.</span><span style="color:#61aeee">getBean</span><span style="color:#999999">(</span><span style="color:#669900">"jedisPool"</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
- <span style="color:#c678dd">try</span> <span style="color:#999999">{</span>
- Jedis jedis <span style="color:#669900">=</span> pool<span style="color:#999999">.</span><span style="color:#61aeee">getResource</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
-
- jedis<span style="color:#999999">.</span><span style="color:#61aeee">set</span><span style="color:#999999">(</span><span style="color:#669900">"name"</span><span style="color:#999999">,</span> <span style="color:#669900">"lisi"</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
- String name <span style="color:#669900">=</span> jedis<span style="color:#999999">.</span><span style="color:#61aeee">get</span><span style="color:#999999">(</span><span style="color:#669900">"name"</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
- System<span style="color:#999999">.</span>out<span style="color:#999999">.</span><span style="color:#61aeee">println</span><span style="color:#999999">(</span>name<span style="color:#999999">)</span><span style="color:#999999">;</span>
- <span style="color:#999999">}</span><span style="color:#c678dd">catch</span><span style="color:#999999">(</span>Exception ex<span style="color:#999999">)</span><span style="color:#999999">{</span>
- ex<span style="color:#999999">.</span><span style="color:#61aeee">printStackTrace</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
- <span style="color:#999999">}</span><span style="color:#c678dd">finally</span><span style="color:#999999">{</span>
- <span style="color:#c678dd">if</span><span style="color:#999999">(</span>jedis <span style="color:#669900">!=</span> null<span style="color:#999999">)</span><span style="color:#999999">{</span>
- <span style="color:#5c6370">//关闭连接</span>
- jedis<span style="color:#999999">.</span><span style="color:#61aeee">close</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
- <span style="color:#999999">}</span>
- <span style="color:#999999">}</span>
- <span style="color:#999999">}</span>
- </code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
八、redis数据类型
Redis支持五种数据类型:
string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。
8.1、String类型
- string 是 redis 最基本的类型,你可以理解成与 Memcached 一模一样的类型,一个 key 对应一个 value。
- string 类型是二进制安全的。意思是 redis 的 string 可以包含任何数据。比如jpg图片或者序列化的对象。
- string 类型是 Redis 最基本的数据类型,string 类型的值最大能存储 512MB。
赋值:
- <span style="color:#000000"><code>SET key value
- 127.0.0.1:6379> set test 123
- OK
- </code></span>
- 1
- 2
- 3
取值:
- <span style="color:#000000"><code class="language-sql"><span style="color:#5c6370"># 当键不存在时返回空结果。</span>
- GET <span style="color:#c678dd">key</span>
- <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> get test
- "<span style="color:#98c379">123</span>“
- </code></span>
- 1
- 2
- 3
- 4
取值时同时对key进行赋值操作
- <span style="color:#000000"><code class="language-sql">GETSET <span style="color:#c678dd">key</span> <span style="color:#c678dd">value</span>
- </code></span>
- 1
删除:
- <span style="color:#000000"><code class="language-sql">Del <span style="color:#c678dd">key</span>
- <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> del test
- <span style="color:#999999">(</span><span style="color:#c678dd">integer</span><span style="color:#999999">)</span> <span style="color:#98c379">1</span>
- </code></span>
- 1
- 2
- 3
数值增减:
- 递增:
INCR key
当存储的字符串是整数时,Redis提供了一个实用的命令INCR,其作用是让当前键值递增,并返回递增后的值。
- <span style="color:#000000"><code class="language-sql"><span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> incr num
- <span style="color:#999999">(</span><span style="color:#c678dd">integer</span><span style="color:#999999">)</span> <span style="color:#98c379">1</span>
- <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> incr num
- <span style="color:#999999">(</span><span style="color:#c678dd">integer</span><span style="color:#999999">)</span> <span style="color:#98c379">2</span>
- <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> incr num
- <span style="color:#999999">(</span><span style="color:#c678dd">integer</span><span style="color:#999999">)</span> <span style="color:#98c379">3</span>
- </code></span>
- 1
- 2
- 3
- 4
- 5
- 6
增加指定的整数
INCRBY key increment
示例:
- <span style="color:#000000"><code class="language-sql"><span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> incrby num <span style="color:#98c379">2</span>
- <span style="color:#999999">(</span><span style="color:#c678dd">integer</span><span style="color:#999999">)</span> <span style="color:#98c379">5</span>
- <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> incrby num <span style="color:#98c379">2</span>
- <span style="color:#999999">(</span><span style="color:#c678dd">integer</span><span style="color:#999999">)</span> <span style="color:#98c379">7</span>
- <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> incrby num <span style="color:#98c379">2</span>
- <span style="color:#999999">(</span><span style="color:#c678dd">integer</span><span style="color:#999999">)</span> <span style="color:#98c379">9</span>
- </code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 递减
语法:DECR key
减少指定的整数:
DECRBY key decrement
示例:
- <span style="color:#000000"><code class="language-sql"><span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> decr num
- <span style="color:#999999">(</span><span style="color:#c678dd">integer</span><span style="color:#999999">)</span> <span style="color:#98c379">6</span>
- <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> decr num
- <span style="color:#999999">(</span><span style="color:#c678dd">integer</span><span style="color:#999999">)</span> <span style="color:#98c379">5</span>
- <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> decrby num <span style="color:#98c379">3</span>
- <span style="color:#999999">(</span><span style="color:#c678dd">integer</span><span style="color:#999999">)</span> <span style="color:#98c379">2</span>
- <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> decrby num <span style="color:#98c379">3</span>
- <span style="color:#999999">(</span><span style="color:#c678dd">integer</span><span style="color:#999999">)</span> <span style="color:#669900">-</span><span style="color:#98c379">1</span>
- </code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
向尾部追加值
语法:APPEND key value
APPEND的作用是向键值的末尾追加value。如果键不存在则将该键的值设置为value,即相当于 SET key value。返回值是追加后字符串的总长度。
- <span style="color:#000000"><code class="language-sql"><span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> <span style="color:#c678dd">set</span> str hello
- OK
- <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> append str <span style="color:#669900">" world!"</span>
- <span style="color:#999999">(</span><span style="color:#c678dd">integer</span><span style="color:#999999">)</span> <span style="color:#98c379">12</span>
- <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> get str
- <span style="color:#669900">"hello world!"</span>
- </code></span>
- 1
- 2
- 3
- 4
- 5
- 6
获取字符串长度
语法:STRLEN key
STRLEN命令返回键值的长度,如果键不存在则返回0。
- <span style="color:#000000"><code class="language-sql"><span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> strlen str
- <span style="color:#999999">(</span><span style="color:#c678dd">integer</span><span style="color:#999999">)</span> <span style="color:#98c379">0</span>
- <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> <span style="color:#c678dd">set</span> str hello
- OK
- <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> strlen str
- <span style="color:#999999">(</span><span style="color:#c678dd">integer</span><span style="color:#999999">)</span> <span style="color:#98c379">5</span>
- </code></span>
- 1
- 2
- 3
- 4
- 5
- 6
同时设置/获取多个键值
MSET key value [key value …]
MGET key [key …]
- <span style="color:#000000"><code class="language-sql"><span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> mset k1 v1 k2 v2 k3 v3
- OK
- <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> get k1
- <span style="color:#669900">"v1"</span>
- <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> mget k1 k3
- <span style="color:#98c379">1</span><span style="color:#999999">)</span> <span style="color:#669900">"v1"</span>
- <span style="color:#98c379">2</span><span style="color:#999999">)</span> <span style="color:#669900">"v3"</span>
- </code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
String类型应用场景:
自增主键:商品编号、订单号采用string的递增数字特性生成。
- <span style="color:#000000"><code class="language-sql">定义商品编号<span style="color:#c678dd">key</span>:items:id
- <span style="color:#98c379">192.168</span><span style="color:#98c379">.101</span><span style="color:#98c379">.3</span>:<span style="color:#98c379">7003</span><span style="color:#669900">></span> INCR items:id
- <span style="color:#999999">(</span><span style="color:#c678dd">integer</span><span style="color:#999999">)</span> <span style="color:#98c379">2</span>
- <span style="color:#98c379">192.168</span><span style="color:#98c379">.101</span><span style="color:#98c379">.3</span>:<span style="color:#98c379">7003</span><span style="color:#669900">></span> INCR items:id
- <span style="color:#999999">(</span><span style="color:#c678dd">integer</span><span style="color:#999999">)</span> <span style="color:#98c379">3</span>
- </code></span>
- 1
- 2
- 3
- 4
- 5
8.2、Hash类型
redis使用string类型存在的问题:
假设有User对象以JSON序列化的形式存储到Redis中,User对象有id,username、password、age、name等属性,存储的过程如下:
保存、更新:
User对象 ——>json(string) ——> redis
如果在业务上只是更新age属性,其他的属性并不做更新我应该怎么做呢? 如果仍然采用上边的方法在传输、处理时会造成资源浪费,下边讲的hash可以很好的解决这个问题。
redis hash介绍
hash叫散列类型,它提供了字段和字段值的映射。字段值只能是字符串类型,不支持散列类型、集合类型等其它类型。如下:
Hash命令
赋值:
HSET key field value 一次只能设置一个字段值
- <span style="color:#000000"><code class="language-sql"><span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> hset <span style="color:#c678dd">user</span> username zhangsan
- <span style="color:#999999">(</span><span style="color:#c678dd">integer</span><span style="color:#999999">)</span> <span style="color:#98c379">1</span>
- </code></span>
- 1
- 2
HMSET key field value [field value …] 一次可以设置多个字段值
- <span style="color:#000000"><code class="language-sql"><span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> hmset <span style="color:#c678dd">user</span> age <span style="color:#98c379">20</span> username lisi
- OK
- </code></span>
- 1
- 2
取值:
HGET key field 一次只能获取一个字段值
- <span style="color:#000000"><code class="language-sql"><span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> hget <span style="color:#c678dd">user</span> username
- "zhangsan“
- </code></span>
- 1
- 2
HMGET key field [field …] 一次可以获取多个字段值
- <span style="color:#000000"><code class="language-sql"><span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> hmget <span style="color:#c678dd">user</span> age username
- <span style="color:#98c379">1</span><span style="color:#999999">)</span> <span style="color:#669900">"20"</span>
- <span style="color:#98c379">2</span><span style="color:#999999">)</span> <span style="color:#669900">"lisi"</span>
- </code></span>
- 1
- 2
- 3
HGETALL key
- <span style="color:#000000"><code class="language-sql"><span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> hgetall <span style="color:#c678dd">user</span>
- <span style="color:#98c379">1</span><span style="color:#999999">)</span> <span style="color:#669900">"age"</span>
- <span style="color:#98c379">2</span><span style="color:#999999">)</span> <span style="color:#669900">"20"</span>
- <span style="color:#98c379">3</span><span style="color:#999999">)</span> <span style="color:#669900">"username"</span>
- <span style="color:#98c379">4</span><span style="color:#999999">)</span> <span style="color:#669900">"lisi"</span>
- </code></span>
- 1
- 2
- 3
- 4
- 5
HSET命令不区分插入和更新操作,当执行插入操作时HSET命令返回1,当执行更新操作时返回0.
删除:
可以删除一个或多个字段,返回值是被删除的字段个数
HDEL key field [field …]
- <span style="color:#000000"><code class="language-sql"><span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> hdel <span style="color:#c678dd">user</span> age
- <span style="color:#999999">(</span><span style="color:#c678dd">integer</span><span style="color:#999999">)</span> <span style="color:#98c379">1</span>
- <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> hdel <span style="color:#c678dd">user</span> age name
- <span style="color:#999999">(</span><span style="color:#c678dd">integer</span><span style="color:#999999">)</span> <span style="color:#98c379">0</span>
- <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> hdel <span style="color:#c678dd">user</span> age username
- <span style="color:#999999">(</span><span style="color:#c678dd">integer</span><span style="color:#999999">)</span> <span style="color:#98c379">1</span>
- </code></span>
- 1
- 2
- 3
- 4
- 5
- 6
增加数字:
HINCRBY key field increment
- <span style="color:#000000"><code class="language-sql"><span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> hincrby <span style="color:#c678dd">user</span> age <span style="color:#98c379">2</span> 将用户的年龄加<span style="color:#98c379">2</span>
- <span style="color:#999999">(</span><span style="color:#c678dd">integer</span><span style="color:#999999">)</span> <span style="color:#98c379">22</span>
- <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> hget <span style="color:#c678dd">user</span> age 获取用户的年龄
- "<span style="color:#98c379">22</span>“
- </code></span>
- 1
- 2
- 3
- 4
其他命令:
判断字段是否存在
HEXISTS key field
- <span style="color:#000000"><code class="language-sql"><span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> hexists <span style="color:#c678dd">user</span> age 查看<span style="color:#c678dd">user</span>中是否有age字段
- <span style="color:#999999">(</span><span style="color:#c678dd">integer</span><span style="color:#999999">)</span> <span style="color:#98c379">1</span>
- <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> hexists <span style="color:#c678dd">user</span> name 查看<span style="color:#c678dd">user</span>中是否有name字段
- <span style="color:#999999">(</span><span style="color:#c678dd">integer</span><span style="color:#999999">)</span> <span style="color:#98c379">0</span>
- </code></span>
- 1
- 2
- 3
- 4
HSETNX key field value
当字段不存在时赋值,类似HSET,区别在于如果字段已经存在,该命令不执行任何操作。
- <span style="color:#000000"><code class="language-sql"><span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> hsetnx <span style="color:#c678dd">user</span> age <span style="color:#98c379">30</span> 如果<span style="color:#c678dd">user</span>中没有age字段则设置age值为<span style="color:#98c379">30</span>,否则不做任何操作
- <span style="color:#999999">(</span><span style="color:#c678dd">integer</span><span style="color:#999999">)</span> <span style="color:#98c379">0</span>
- </code></span>
- 1
- 2
只获取字段名或字段值
HKEYS key
HVALS key
- <span style="color:#000000"><code class="language-sql"><span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> hmset <span style="color:#c678dd">user</span> age <span style="color:#98c379">20</span> name lisi
- OK
- <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> hkeys <span style="color:#c678dd">user</span>
- <span style="color:#98c379">1</span><span style="color:#999999">)</span> <span style="color:#669900">"age"</span>
- <span style="color:#98c379">2</span><span style="color:#999999">)</span> <span style="color:#669900">"name"</span>
- <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> hvals <span style="color:#c678dd">user</span>
- <span style="color:#98c379">1</span><span style="color:#999999">)</span> <span style="color:#669900">"20"</span>
- <span style="color:#98c379">2</span><span style="color:#999999">)</span> <span style="color:#669900">"lisi"</span>
- </code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
获取字段数量
HLEN key
- <span style="color:#000000"><code class="language-sql"><span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> hlen <span style="color:#c678dd">user</span>
- <span style="color:#999999">(</span><span style="color:#c678dd">integer</span><span style="color:#999999">)</span> <span style="color:#98c379">2</span>
- </code></span>
- 1
- 2
Hash类型应用场景:
商品id、商品名称、商品描述、商品库存、商品好评
定义商品信息的key:
商品1001的信息在 redis中的key为:items:1001
存储商品信息
- <span style="color:#000000"><code class="language-sql"><span style="color:#98c379">192.168</span><span style="color:#98c379">.101</span><span style="color:#98c379">.3</span>:<span style="color:#98c379">7003</span><span style="color:#669900">></span> HMSET items:<span style="color:#98c379">1001</span> id <span style="color:#98c379">3</span> name apple price <span style="color:#98c379">999.9</span>
- OK
- </code></span>
- 1
- 2
获取商品信息
- <span style="color:#000000"><code class="language-sql"><span style="color:#98c379">192.168</span><span style="color:#98c379">.101</span><span style="color:#98c379">.3</span>:<span style="color:#98c379">7003</span><span style="color:#669900">></span> HGET items:<span style="color:#98c379">1001</span> id
- <span style="color:#669900">"3"</span>
- <span style="color:#98c379">192.168</span><span style="color:#98c379">.101</span><span style="color:#98c379">.3</span>:<span style="color:#98c379">7003</span><span style="color:#669900">></span> HGETALL items:<span style="color:#98c379">1001</span>
- <span style="color:#98c379">1</span><span style="color:#999999">)</span> <span style="color:#669900">"id"</span>
- <span style="color:#98c379">2</span><span style="color:#999999">)</span> <span style="color:#669900">"3"</span>
- <span style="color:#98c379">3</span><span style="color:#999999">)</span> <span style="color:#669900">"name"</span>
- <span style="color:#98c379">4</span><span style="color:#999999">)</span> <span style="color:#669900">"apple"</span>
- <span style="color:#98c379">5</span><span style="color:#999999">)</span> <span style="color:#669900">"price"</span>
- <span style="color:#98c379">6</span><span style="color:#999999">)</span> <span style="color:#669900">"999.9"</span>
- </code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
8.3、list类型
ArrayList与LinkedList的区别
ArrayList使用数组方式存储数据,所以根据索引查询数据速度快,而新增或者删除元素时需要设计到位移操作,所以比较慢。
LinkedList使用双向链接方式存储数据,每个元素都记录前后元素的指针,所以插入、删除数据时只是更改前后元素的指针指向即可,速度非常快,然后通过下标查询元素时需要从头开始索引,所以比较慢,但是如果查询前几个元素或后几个元素速度比较快。
redis list介绍
列表类型(list)可以存储一个有序的字符串列表,常用的操作是向列表两端添加元素,或者获得列表的某一个片段。
列表类型内部是使用双向链表(double linked list)实现的,所以向列表两端添加元素的时间复杂度为0(1),获取越接近两端的元素速度就越快。这意味着即使是一个有几千万个元素的列表,获取头部或尾部的10条记录也是极快的。
list类型命令
向列表两端增加元素
LPUSH key value [value …]
RPUSH key value [value …]
向列表左边增加元素
- <span style="color:#000000"><code class="language-sql"><span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> lpush list:<span style="color:#98c379">1</span> <span style="color:#98c379">1</span> <span style="color:#98c379">2</span> <span style="color:#98c379">3</span>
- <span style="color:#999999">(</span><span style="color:#c678dd">integer</span><span style="color:#999999">)</span> <span style="color:#98c379">3</span>
- </code></span>
- 1
- 2
向列表右边增加元素
- <span style="color:#000000"><code class="language-sql"><span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> rpush list:<span style="color:#98c379">1</span> <span style="color:#98c379">4</span> <span style="color:#98c379">5</span> <span style="color:#98c379">6</span>
- <span style="color:#999999">(</span><span style="color:#c678dd">integer</span><span style="color:#999999">)</span> <span style="color:#98c379">3</span>
- </code></span>
- 1
- 2
查看列表
LRANGE key start stop
LRANGE命令是列表类型最常用的命令之一,获取列表中的某一片段,将返回start、stop之间的所有元素(包含两端的元素),索引从0开始。索引可以是负数,如:“-1”代表最后边的一个元素。
- <span style="color:#000000"><code class="language-sql"><span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> lrange list:<span style="color:#98c379">1</span> <span style="color:#98c379">0</span> <span style="color:#98c379">2</span>
- <span style="color:#98c379">1</span><span style="color:#999999">)</span> <span style="color:#669900">"2"</span>
- <span style="color:#98c379">2</span><span style="color:#999999">)</span> <span style="color:#669900">"1"</span>
- <span style="color:#98c379">3</span><span style="color:#999999">)</span> <span style="color:#669900">"4"</span>
- </code></span>
- 1
- 2
- 3
- 4
从列表两端弹出元素
LPOP key
RPOP key
LPOP命令从列表左边弹出一个元素,会分两步完成,第一步是将列表左边的元素从列表中移除,第二步是返回被移除的元素值。
- <span style="color:#000000"><code class="language-sql"><span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> lpop list:<span style="color:#98c379">1</span>
- <span style="color:#669900">"3“
- 127.0.0.1:6379> rpop list:1
- "</span><span style="color:#98c379">6</span>“
- </code></span>
- 1
- 2
- 3
- 4
获取列表中元素的个数
LLEN key
- <span style="color:#000000"><code class="language-sql"><span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> llen list:<span style="color:#98c379">1</span>
- <span style="color:#999999">(</span><span style="color:#c678dd">integer</span><span style="color:#999999">)</span> <span style="color:#98c379">2</span>
- </code></span>
- 1
- 2
删除列表中指定的值
LREM key count value
LREM命令会删除列表中前count个值为value的元素,返回实际删除的元素个数。根据count值的不同,该命令的执行方式会有所不同:
当count>0时, LREM会从列表左边开始删除。
当count<0时, LREM会从列表后边开始删除。
当count=0时, LREM删除所有值为value的元素。
获得/设置指定索引的元素值
LINDEX key index
LSET key index value
- <span style="color:#000000"><code class="language-sql"><span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> lindex l:list <span style="color:#98c379">2</span>
- <span style="color:#669900">"1"</span>
- <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> lset l:list <span style="color:#98c379">2</span> <span style="color:#98c379">2</span>
- OK
- <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> lrange l:list <span style="color:#98c379">0</span> <span style="color:#669900">-</span><span style="color:#98c379">1</span>
- <span style="color:#98c379">1</span><span style="color:#999999">)</span> <span style="color:#669900">"6"</span>
- <span style="color:#98c379">2</span><span style="color:#999999">)</span> <span style="color:#669900">"5"</span>
- <span style="color:#98c379">3</span><span style="color:#999999">)</span> <span style="color:#669900">"2"</span>
- <span style="color:#98c379">4</span><span style="color:#999999">)</span> <span style="color:#669900">"2"</span>
- </code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
只保留列表指定片段,指定范围和LRANGE一致
LTRIM key start stop
- <span style="color:#000000"><code class="language-sql"><span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> lrange l:list <span style="color:#98c379">0</span> <span style="color:#669900">-</span><span style="color:#98c379">1</span>
- <span style="color:#98c379">1</span><span style="color:#999999">)</span> <span style="color:#669900">"6"</span>
- <span style="color:#98c379">2</span><span style="color:#999999">)</span> <span style="color:#669900">"5"</span>
- <span style="color:#98c379">3</span><span style="color:#999999">)</span> <span style="color:#669900">"0"</span>
- <span style="color:#98c379">4</span><span style="color:#999999">)</span> <span style="color:#669900">"2"</span>
- <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> ltrim l:list <span style="color:#98c379">0</span> <span style="color:#98c379">2</span>
- OK
- <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> lrange l:list <span style="color:#98c379">0</span> <span style="color:#669900">-</span><span style="color:#98c379">1</span>
- <span style="color:#98c379">1</span><span style="color:#999999">)</span> <span style="color:#669900">"6"</span>
- <span style="color:#98c379">2</span><span style="color:#999999">)</span> <span style="color:#669900">"5"</span>
- <span style="color:#98c379">3</span><span style="color:#999999">)</span> <span style="color:#669900">"0"</span>
- </code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
向列表中插入元素
LINSERT key BEFORE|AFTER pivot value
该命令首先会在列表中从左到右查找值为pivot的元素,然后根据第二个参数是BEFORE还是AFTER来决定将value插入到该元素的前面还是后面。
- <span style="color:#000000"><code class="language-sql"><span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> lrange list <span style="color:#98c379">0</span> <span style="color:#669900">-</span><span style="color:#98c379">1</span>
- <span style="color:#98c379">1</span><span style="color:#999999">)</span> <span style="color:#669900">"3"</span>
- <span style="color:#98c379">2</span><span style="color:#999999">)</span> <span style="color:#669900">"2"</span>
- <span style="color:#98c379">3</span><span style="color:#999999">)</span> <span style="color:#669900">"1"</span>
- <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> linsert list <span style="color:#c678dd">after</span> <span style="color:#98c379">3</span> <span style="color:#98c379">4</span>
- <span style="color:#999999">(</span><span style="color:#c678dd">integer</span><span style="color:#999999">)</span> <span style="color:#98c379">4</span>
- <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> lrange list <span style="color:#98c379">0</span> <span style="color:#669900">-</span><span style="color:#98c379">1</span>
- <span style="color:#98c379">1</span><span style="color:#999999">)</span> <span style="color:#669900">"3"</span>
- <span style="color:#98c379">2</span><span style="color:#999999">)</span> <span style="color:#669900">"4"</span>
- <span style="color:#98c379">3</span><span style="color:#999999">)</span> <span style="color:#669900">"2"</span>
- <span style="color:#98c379">4</span><span style="color:#999999">)</span> <span style="color:#669900">"1"</span>
- </code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
将元素从一个列表转移到另一个列表中
RPOPLPUSH source destination
- <span style="color:#000000"><code class="language-sql"><span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> rpoplpush list newlist
- <span style="color:#669900">"1"</span>
- <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> lrange newlist <span style="color:#98c379">0</span> <span style="color:#669900">-</span><span style="color:#98c379">1</span>
- <span style="color:#98c379">1</span><span style="color:#999999">)</span> <span style="color:#669900">"1"</span>
- <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> lrange list <span style="color:#98c379">0</span> <span style="color:#669900">-</span><span style="color:#98c379">1</span>
- <span style="color:#98c379">1</span><span style="color:#999999">)</span> <span style="color:#669900">"3"</span>
- <span style="color:#98c379">2</span><span style="color:#999999">)</span> <span style="color:#669900">"4"</span>
- <span style="color:#98c379">3</span><span style="color:#999999">)</span> <span style="color:#669900">"2"</span>
- </code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
list类型应用场景
在redis中创建商品评论列表
用户发布商品评论,将评论信息转成json存储到list中。
用户在页面查询评论列表,从redis中取出json数据展示到页面。
定义商品评论列表key:
商品编号为1001的商品评论key:items: comment:1001
- <span style="color:#000000"><code class="language-sql"><span style="color:#98c379">192.168</span><span style="color:#98c379">.237</span><span style="color:#98c379">.129</span>:<span style="color:#98c379">7001</span><span style="color:#669900">></span> LPUSH items:<span style="color:#c678dd">comment</span>:<span style="color:#98c379">1001</span> <span style="color:#669900">'{"id":1,"name":"商品不错,很好!!","date":1430295077289}'</span>
- </code></span>
- 1
8.4、set类型
set类型介绍
在set集合中的每个元素都是不同的,且没有顺序。
集合类型和列表类型的对比:
集合类型的常用操作是向集合中加入或删除元素、判断某个元素是否存在等,由于集合类型的Redis内部是使用值为空的散列表实现,所有这些操作的时间复杂度都为0(1)。
Redis还提供了多个集合之间的交集、并集、差集的运算。
set类型常用命令
增加/删除元素
SADD key member [member …]
SREM key member [member …]
- <span style="color:#000000"><code class="language-sql"><span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> sadd <span style="color:#c678dd">set</span> a b c
- <span style="color:#999999">(</span><span style="color:#c678dd">integer</span><span style="color:#999999">)</span> <span style="color:#98c379">3</span>
- <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> sadd <span style="color:#c678dd">set</span> a
- <span style="color:#999999">(</span><span style="color:#c678dd">integer</span><span style="color:#999999">)</span> <span style="color:#98c379">0</span>
- <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> srem <span style="color:#c678dd">set</span> c d
- <span style="color:#999999">(</span><span style="color:#c678dd">integer</span><span style="color:#999999">)</span> <span style="color:#98c379">1</span>
- </code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- <span style="color:#000000"><code>获得集合中的所有元素
- </code></span>
- 1
SMEMBERS key
- <span style="color:#000000"><code class="language-sql"><span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> smembers <span style="color:#c678dd">set</span>
- <span style="color:#98c379">1</span><span style="color:#999999">)</span> <span style="color:#669900">"b"</span>
- <span style="color:#98c379">2</span><span style="color:#999999">)</span> "a”
- </code></span>
- 1
- 2
- 3
判断元素是否在集合中,无论集合中有多少元素都可以极速的返回结果。
SISMEMBER key member
- <span style="color:#000000"><code class="language-sql"><span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> sismember <span style="color:#c678dd">set</span> a
- <span style="color:#999999">(</span><span style="color:#c678dd">integer</span><span style="color:#999999">)</span> <span style="color:#98c379">1</span>
- <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> sismember <span style="color:#c678dd">set</span> h
- <span style="color:#999999">(</span><span style="color:#c678dd">integer</span><span style="color:#999999">)</span> <span style="color:#98c379">0</span>
- </code></span>
- 1
- 2
- 3
- 4
集合的差集运算 A-B
属于A并且不属于B的元素构成的集合。
SDIFF key [key …]
- <span style="color:#000000"><code class="language-sql"><span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> sadd setA <span style="color:#98c379">1</span> <span style="color:#98c379">2</span> <span style="color:#98c379">3</span>
- <span style="color:#999999">(</span><span style="color:#c678dd">integer</span><span style="color:#999999">)</span> <span style="color:#98c379">3</span>
- <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> sadd setB <span style="color:#98c379">2</span> <span style="color:#98c379">3</span> <span style="color:#98c379">4</span>
- <span style="color:#999999">(</span><span style="color:#c678dd">integer</span><span style="color:#999999">)</span> <span style="color:#98c379">3</span>
- <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> sdiff setA setB
- <span style="color:#98c379">1</span><span style="color:#999999">)</span> <span style="color:#669900">"1"</span>
- <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> sdiff setB setA
- <span style="color:#98c379">1</span><span style="color:#999999">)</span> <span style="color:#669900">"4"</span>
- </code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
集合的交集运算 A ∩ B
属于A且属于B的元素构成的集合
SINTER key [key …]
- <span style="color:#000000"><code class="language-sql"><span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> sinter setA setB
- <span style="color:#98c379">1</span><span style="color:#999999">)</span> <span style="color:#669900">"2"</span>
- <span style="color:#98c379">2</span><span style="color:#999999">)</span> <span style="color:#669900">"3"</span>
- </code></span>
- 1
- 2
- 3
集合的并集运算 A ∪ B
属于A或者属于B的元素构成的集合
SUNION key [key …]
- <span style="color:#000000"><code class="language-sql"><span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> sunion setA setB
- <span style="color:#98c379">1</span><span style="color:#999999">)</span> <span style="color:#669900">"1"</span>
- <span style="color:#98c379">2</span><span style="color:#999999">)</span> <span style="color:#669900">"2"</span>
- <span style="color:#98c379">3</span><span style="color:#999999">)</span> <span style="color:#669900">"3"</span>
- <span style="color:#98c379">4</span><span style="color:#999999">)</span> <span style="color:#669900">"4"</span>
- </code></span>
- 1
- 2
- 3
- 4
- 5
获得集合中元素的个数
SCARD key
- <span style="color:#000000"><code class="language-sql"><span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> smembers setA
- <span style="color:#98c379">1</span><span style="color:#999999">)</span> <span style="color:#669900">"1"</span>
- <span style="color:#98c379">2</span><span style="color:#999999">)</span> <span style="color:#669900">"2"</span>
- <span style="color:#98c379">3</span><span style="color:#999999">)</span> <span style="color:#669900">"3"</span>
- <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> scard setA
- <span style="color:#999999">(</span><span style="color:#c678dd">integer</span><span style="color:#999999">)</span> <span style="color:#98c379">3</span>
- </code></span>
- 1
- 2
- 3
- 4
- 5
- 6
从集合中弹出一个元素
SPOP key
- <span style="color:#000000"><code class="language-sql"><span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> spop setA
- "<span style="color:#98c379">1</span>“
- </code></span>
- 1
- 2
注意:由于集合是无序的,所有SPOP命令会从集合中随机选择一个元素弹出
8.5、sorted类型
sorted set类型介绍
在集合类型的基础上,有序集合类型(sorted set)为集合中的每个元素都关联一个分数,这使得我们不仅可以完成插入、删除和判断元素是否存在在集合中,还能够获得分数最高或最低的前N个元素、获取指定分数范围内的元素等与分数有关的操作。
在某些方面有序集合和列表类型有些相似。
1、二者都是有序的。
2、二者都可以获得某一范围的元素。
但是,二者有着很大区别:
1、列表类型是通过链表实现的,获取靠近两端的数据速度极快,而当元素增多后,访问中间数据的速度会变慢。
2、有序集合类型使用散列表实现,所有即使读取位于中间部分的数据也很快。
3、列表中不能简单的调整某个元素的位置,但是有序集合可以(通过更改分数实现)
4、有序集合要比列表类型更耗内存。
sorted set类型常用命令
增加元素
向有序集合中加入一个元素和该元素的分数,如果该元素已经存在则会用新的分数替换原有的分数。返回值是新加入到集合中的元素个数,不包含之前已经存在的元素。
ZADD key score member [score member …]
- <span style="color:#000000"><code class="language-sql"><span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> zadd scoreboard <span style="color:#98c379">80</span> zhangsan <span style="color:#98c379">89</span> lisi <span style="color:#98c379">94</span> wangwu
- <span style="color:#999999">(</span><span style="color:#c678dd">integer</span><span style="color:#999999">)</span> <span style="color:#98c379">3</span>
- <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> zadd scoreboard <span style="color:#98c379">97</span> lisi
- <span style="color:#999999">(</span><span style="color:#c678dd">integer</span><span style="color:#999999">)</span> <span style="color:#98c379">0</span>
- </code></span>
- 1
- 2
- 3
- 4
获取元素的分数
ZSCORE key member
- <span style="color:#000000"><code class="language-sql"><span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> zscore scoreboard lisi
- </code></span>
- 1
删除元素
ZREM key member [member …]
移除有序集key中的一个或多个成员,不存在的成员将被忽略。
当key存在但不是有序集类型时,返回一个错误。
- <span style="color:#000000"><code class="language-sql"><span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> zrem scoreboard lisi
- <span style="color:#999999">(</span><span style="color:#c678dd">integer</span><span style="color:#999999">)</span> <span style="color:#98c379">1</span>
- </code></span>
- 1
- 2
获得排名在某个范围的元素列表
获得排名在某个范围的元素列表
ZRANGE key start stop [WITHSCORES] 照元素分数从小到大的顺序返回索引从start到stop之间的所有元素(包含两端的元素)
- <span style="color:#000000"><code class="language-sql"><span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> zrange scoreboard <span style="color:#98c379">0</span> <span style="color:#98c379">2</span>
- <span style="color:#98c379">1</span><span style="color:#999999">)</span> <span style="color:#669900">"zhangsan"</span>
- <span style="color:#98c379">2</span><span style="color:#999999">)</span> <span style="color:#669900">"wangwu"</span>
- <span style="color:#98c379">3</span><span style="color:#999999">)</span> "lisi“
- </code></span>
- 1
- 2
- 3
- 4
ZREVRANGE key start stop [WITHSCORES] 照元素分数从大到小的顺序返回索引从start到stop之间的所有元素(包含两端的元素)
- <span style="color:#000000"><code class="language-sql"><span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> zrevrange scoreboard <span style="color:#98c379">0</span> <span style="color:#98c379">2</span>
- <span style="color:#98c379">1</span><span style="color:#999999">)</span> <span style="color:#669900">" lisi "</span>
- <span style="color:#98c379">2</span><span style="color:#999999">)</span> <span style="color:#669900">"wangwu"</span>
- <span style="color:#98c379">3</span><span style="color:#999999">)</span> " zhangsan “
- </code></span>
- 1
- 2
- 3
- 4
如果需要获得元素的分数的可以在命令尾部加上WITHSCORES参数
- <span style="color:#000000"><code class="language-sql"><span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> zrange scoreboard <span style="color:#98c379">0</span> <span style="color:#98c379">1</span> WITHSCORES
- <span style="color:#98c379">1</span><span style="color:#999999">)</span> <span style="color:#669900">"zhangsan"</span>
- <span style="color:#98c379">2</span><span style="color:#999999">)</span> <span style="color:#669900">"80"</span>
- <span style="color:#98c379">3</span><span style="color:#999999">)</span> <span style="color:#669900">"wangwu"</span>
- <span style="color:#98c379">4</span><span style="color:#999999">)</span> <span style="color:#669900">"94"</span>
- </code></span>
- 1
- 2
- 3
- 4
- 5
获得指定分数范围的元素
ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
- <span style="color:#000000"><code class="language-sql"><span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> ZRANGEBYSCORE scoreboard <span style="color:#98c379">90</span> <span style="color:#98c379">97</span> WITHSCORES
- <span style="color:#98c379">1</span><span style="color:#999999">)</span> <span style="color:#669900">"wangwu"</span>
- <span style="color:#98c379">2</span><span style="color:#999999">)</span> <span style="color:#669900">"94"</span>
- <span style="color:#98c379">3</span><span style="color:#999999">)</span> <span style="color:#669900">"lisi"</span>
- <span style="color:#98c379">4</span><span style="color:#999999">)</span> <span style="color:#669900">"97"</span>
- <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> ZRANGEBYSCORE scoreboard <span style="color:#98c379">70</span> <span style="color:#98c379">100</span> <span style="color:#c678dd">limit</span> <span style="color:#98c379">1</span> <span style="color:#98c379">2</span>
- <span style="color:#98c379">1</span><span style="color:#999999">)</span> <span style="color:#669900">"wangwu"</span>
- <span style="color:#98c379">2</span><span style="color:#999999">)</span> <span style="color:#669900">"lisi"</span>
- </code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
增加某个元素的分数,返回值是更改后的分数。
ZINCRBY key increment member
给lisi加4分
- <span style="color:#000000"><code class="language-sql"><span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> ZINCRBY scoreboard <span style="color:#98c379">4</span> lisi
- "<span style="color:#98c379">101</span>“
- </code></span>
- 1
- 2
- <span style="color:#000000"><code>获得集合中元素的数量
- </code></span>
- 1
ZCARD key
- <span style="color:#000000"><code class="language-sql"><span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> ZCARD scoreboard
- <span style="color:#999999">(</span><span style="color:#c678dd">integer</span><span style="color:#999999">)</span> <span style="color:#98c379">3</span>
- </code></span>
- 1
- 2
获得指定分数范围内的元素个数
ZCOUNT key min max
- <span style="color:#000000"><code class="language-sql"><span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> ZCOUNT scoreboard <span style="color:#98c379">80</span> <span style="color:#98c379">90</span>
- <span style="color:#999999">(</span><span style="color:#c678dd">integer</span><span style="color:#999999">)</span> <span style="color:#98c379">1</span>
- </code></span>
- 1
- 2
按照排名范围删除元素
ZREMRANGEBYRANK key start stop
- <span style="color:#000000"><code class="language-sql"><span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> ZREMRANGEBYRANK scoreboard <span style="color:#98c379">0</span> <span style="color:#98c379">1</span>
- <span style="color:#999999">(</span><span style="color:#c678dd">integer</span><span style="color:#999999">)</span> <span style="color:#98c379">2</span>
- <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> ZRANGE scoreboard <span style="color:#98c379">0</span> <span style="color:#669900">-</span><span style="color:#98c379">1</span>
- <span style="color:#98c379">1</span><span style="color:#999999">)</span> <span style="color:#669900">"lisi"</span>
- </code></span>
- 1
- 2
- 3
- 4
ZREMRANGEBYSCORE key min max
按照分数范围删除元素
- <span style="color:#000000"><code class="language-sql"><span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> zadd scoreboard <span style="color:#98c379">84</span> zhangsan
- <span style="color:#999999">(</span><span style="color:#c678dd">integer</span><span style="color:#999999">)</span> <span style="color:#98c379">1</span>
- <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> ZREMRANGEBYSCORE scoreboard <span style="color:#98c379">80</span> <span style="color:#98c379">100</span>
- <span style="color:#999999">(</span><span style="color:#c678dd">integer</span><span style="color:#999999">)</span> <span style="color:#98c379">1</span>
- </code></span>
- 1
- 2
- 3
- 4
获取元素的排名
ZRANK key member
ZREVRANK key member
从小到大
- <span style="color:#000000"><code class="language-sql"><span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> ZRANK scoreboard lisi
- <span style="color:#999999">(</span><span style="color:#c678dd">integer</span><span style="color:#999999">)</span> <span style="color:#98c379">0</span>
- 从大到小
- <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> ZREVRANK scoreboard zhangsan
- <span style="color:#999999">(</span><span style="color:#c678dd">integer</span><span style="color:#999999">)</span> <span style="color:#98c379">1</span>
- </code></span>
- 1
- 2
- 3
- 4
- 5
应用场景
根据商品销售量对商品进行排行显示,定义sorted set集合,商品销售量为元素的分数。
定义商品销售排行榜key:items:sellsort
写入商品销售量:
商品编号1001的销量是9,商品编号1002的销量是10
- <span style="color:#000000"><code class="language-sql"><span style="color:#98c379">192.168</span><span style="color:#98c379">.101</span><span style="color:#98c379">.3</span>:<span style="color:#98c379">7007</span><span style="color:#669900">></span> ZADD items:sellsort <span style="color:#98c379">9</span> <span style="color:#98c379">1001</span> <span style="color:#98c379">10</span> <span style="color:#98c379">1002</span>
- </code></span>
- 1
商品编号1001的销量加1
- <span style="color:#000000"><code class="language-sql"><span style="color:#98c379">192.168</span><span style="color:#98c379">.101</span><span style="color:#98c379">.3</span>:<span style="color:#98c379">7001</span><span style="color:#669900">></span> ZINCRBY items:sellsort <span style="color:#98c379">1</span> <span style="color:#98c379">1001</span>
- </code></span>
- 1
商品销量前10名:
- <span style="color:#000000"><code class="language-sql"><span style="color:#98c379">192.168</span><span style="color:#98c379">.101</span><span style="color:#98c379">.3</span>:<span style="color:#98c379">7001</span><span style="color:#669900">></span> ZRANGE items:sellsort <span style="color:#98c379">0</span> <span style="color:#98c379">9</span> withscores
- </code></span>
- 1
九、keys命令
9.1、设置key的生存时间
Redis在实际使用过程中更多的用作缓存,然而缓存的数据一般都是需要设置生存时间的,即:到期后数据销毁。
- EXPIRE key seconds 设置key的生存时间(单位:秒)key在多少秒后会自动删除
- TTL key 查看key生于的生存时间
- PERSIST key 清除生存时间
- PEXPIRE key milliseconds 生存时间设置单位为:毫秒
例子:
- <span style="color:#000000"><code class="language-sql"><span style="color:#98c379">192.168</span><span style="color:#98c379">.101</span><span style="color:#98c379">.3</span>:<span style="color:#98c379">7002</span><span style="color:#669900">></span> <span style="color:#c678dd">set</span> test <span style="color:#98c379">1</span> 设置test的值为<span style="color:#98c379">1</span>
- OK
- <span style="color:#98c379">192.168</span><span style="color:#98c379">.101</span><span style="color:#98c379">.3</span>:<span style="color:#98c379">7002</span><span style="color:#669900">></span> get test 获取test的值
- <span style="color:#669900">"1"</span>
- <span style="color:#98c379">192.168</span><span style="color:#98c379">.101</span><span style="color:#98c379">.3</span>:<span style="color:#98c379">7002</span><span style="color:#669900">></span> EXPIRE test <span style="color:#98c379">5</span> 设置test的生存时间为<span style="color:#98c379">5</span>秒
- <span style="color:#999999">(</span><span style="color:#c678dd">integer</span><span style="color:#999999">)</span> <span style="color:#98c379">1</span>
- <span style="color:#98c379">192.168</span><span style="color:#98c379">.101</span><span style="color:#98c379">.3</span>:<span style="color:#98c379">7002</span><span style="color:#669900">></span> TTL test 查看test的生于生成时间还有<span style="color:#98c379">1</span>秒删除
- <span style="color:#999999">(</span><span style="color:#c678dd">integer</span><span style="color:#999999">)</span> <span style="color:#98c379">1</span>
- <span style="color:#98c379">192.168</span><span style="color:#98c379">.101</span><span style="color:#98c379">.3</span>:<span style="color:#98c379">7002</span><span style="color:#669900">></span> TTL test
- <span style="color:#999999">(</span><span style="color:#c678dd">integer</span><span style="color:#999999">)</span> <span style="color:#669900">-</span><span style="color:#98c379">2</span>
- <span style="color:#98c379">192.168</span><span style="color:#98c379">.101</span><span style="color:#98c379">.3</span>:<span style="color:#98c379">7002</span><span style="color:#669900">></span> get test 获取test的值,已经删除
- <span style="color:#999999">(</span>nil<span style="color:#999999">)</span>
- </code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
9.2、返回满足给定pattern 的所有key
- <span style="color:#000000"><code class="language-sql">redis <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> <span style="color:#c678dd">keys</span> mylist<span style="color:#669900">*</span>
- <span style="color:#98c379">1</span><span style="color:#999999">)</span> <span style="color:#669900">"mylist"</span>
- <span style="color:#98c379">2</span><span style="color:#999999">)</span> <span style="color:#669900">"mylist5"</span>
- <span style="color:#98c379">3</span><span style="color:#999999">)</span> <span style="color:#669900">"mylist6"</span>
- <span style="color:#98c379">4</span><span style="color:#999999">)</span> <span style="color:#669900">"mylist7"</span>
- <span style="color:#98c379">5</span><span style="color:#999999">)</span> <span style="color:#669900">"mylist8"</span>
- </code></span>
- 1
- 2
- 3
- 4
- 5
- 6
9.3、确认一个key 是否存在
- <span style="color:#000000"><code class="language-sql">redis <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> <span style="color:#c678dd">exists</span> HongWan
- <span style="color:#999999">(</span><span style="color:#c678dd">integer</span><span style="color:#999999">)</span> <span style="color:#98c379">0</span>
- redis <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> <span style="color:#c678dd">exists</span> age
- <span style="color:#999999">(</span><span style="color:#c678dd">integer</span><span style="color:#999999">)</span> <span style="color:#98c379">1</span>
- redis <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span>
- </code></span>
- 1
- 2
- 3
- 4
- 5
从结果来数据库中不存在HongWan 这个key,但是age 这个key 是存在的
9.3、删除一个key
- <span style="color:#000000"><code class="language-sql">redis <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> del age
- <span style="color:#999999">(</span><span style="color:#c678dd">integer</span><span style="color:#999999">)</span> <span style="color:#98c379">1</span>
- redis <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> <span style="color:#c678dd">exists</span> age
- <span style="color:#999999">(</span><span style="color:#c678dd">integer</span><span style="color:#999999">)</span> <span style="color:#98c379">0</span>
- redis <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span>
- </code></span>
- 1
- 2
- 3
- 4
- 5
从结果来数据库中不存在HongWan 这个key,但是age 这个key 是存在的
9.4、重命名key
- <span style="color:#000000"><code class="language-sql">redis <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#999999">[</span><span style="color:#98c379">1</span><span style="color:#999999">]</span><span style="color:#669900">></span> <span style="color:#c678dd">keys</span> <span style="color:#669900">*</span>
- <span style="color:#98c379">1</span><span style="color:#999999">)</span> <span style="color:#669900">"age"</span>
- redis <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#999999">[</span><span style="color:#98c379">1</span><span style="color:#999999">]</span><span style="color:#669900">></span> <span style="color:#c678dd">rename</span> age age_new
- OK
- redis <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#999999">[</span><span style="color:#98c379">1</span><span style="color:#999999">]</span><span style="color:#669900">></span> <span style="color:#c678dd">keys</span> <span style="color:#669900">*</span>
- <span style="color:#98c379">1</span><span style="color:#999999">)</span> <span style="color:#669900">"age_new"</span>
- redis <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#999999">[</span><span style="color:#98c379">1</span><span style="color:#999999">]</span><span style="color:#669900">></span>
- </code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
age 成功的被我们改名为age_new 了
9.5、返回值的类型
- <span style="color:#000000"><code class="language-sql">redis <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> <span style="color:#c678dd">type</span> addr
- string
- redis <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> <span style="color:#c678dd">type</span> myzset2
- zset
- redis <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> <span style="color:#c678dd">type</span> mylist
- list
- redis <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span>
- </code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
这个方法可以非常简单的判断出值的类型
十、服务器命令
ping
测试连接是否存活(返回PONG代表存活)
- <span style="color:#000000"><code class="language-sql">redis <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> ping
- PONG
- </code></span>
- 1
- 2
//执行下面命令之前,我们停止redis 服务器
- <span style="color:#000000"><code class="language-sql">redis <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> ping
- Could <span style="color:#669900">not</span> <span style="color:#c678dd">connect</span> <span style="color:#c678dd">to</span> Redis at <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span>: Connection refused
- </code></span>
- 1
- 2
//执行下面命令之前,我们启动redis 服务器
- <span style="color:#000000"><code class="language-sql"><span style="color:#669900">not</span> connected<span style="color:#669900">></span> ping
- PONG
- redis <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span>
- </code></span>
- 1
- 2
- 3
第一个ping 时,说明此连接正常
第二个ping 之前,我们将redis 服务器停止,那么ping 是失败的
第三个ping 之前,我们将redis 服务器启动,那么ping 是成功的
echo
在命令行打印一些内容
- <span style="color:#000000"><code class="language-sql">redis <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> echo HongWan
- <span style="color:#669900">"HongWan"</span>
- redis <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span>
- </code></span>
- 1
- 2
- 3
select
选择数据库。Redis 数据库编号从0~15,我们可以选择任意一个数据库来进行数据的存取。
- <span style="color:#000000"><code class="language-sql">redis <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> <span style="color:#c678dd">select</span> <span style="color:#98c379">1</span>
- OK
- redis <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#999999">[</span><span style="color:#98c379">1</span><span style="color:#999999">]</span><span style="color:#669900">></span> <span style="color:#c678dd">select</span> <span style="color:#98c379">16</span>
- <span style="color:#999999">(</span>error<span style="color:#999999">)</span> ERR invalid DB <span style="color:#c678dd">index</span>
- redis <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#999999">[</span><span style="color:#98c379">16</span><span style="color:#999999">]</span><span style="color:#669900">></span>
- </code></span>
- 1
- 2
- 3
- 4
- 5
当选择16 时,报错,说明没有编号为16 的这个数据库
quit
退出连接。
- <span style="color:#000000"><code class="language-sql">redis <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> quit
- </code></span>
- 1
dbsize
返回当前数据库中key 的数目。
- <span style="color:#000000"><code class="language-sql">redis <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> dbsize
- <span style="color:#999999">(</span><span style="color:#c678dd">integer</span><span style="color:#999999">)</span> <span style="color:#98c379">18</span>
- redis <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span>
- </code></span>
- 1
- 2
- 3
结果说明此库中有18 个key
info
获取服务器的信息和统计。
- <span style="color:#000000"><code class="language-sql">redis <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> info
- redis_version:<span style="color:#98c379">2.2</span><span style="color:#98c379">.12</span>
- redis_git_sha1:<span style="color:#98c379">00000000</span>
- redis_git_dirty:<span style="color:#98c379">0</span>
- arch_bits:<span style="color:#98c379">32</span>
- multiplexing_api:epoll
- process_id:<span style="color:#98c379">28480</span>
- uptime_in_seconds:<span style="color:#98c379">2515</span>
- uptime_in_days:<span style="color:#98c379">0</span>
- 。。。。
- 。。。。
- </code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
flushdb
删除当前选择数据库中的所有key。
- <span style="color:#000000"><code class="language-sql">redis <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> dbsize
- <span style="color:#999999">(</span><span style="color:#c678dd">integer</span><span style="color:#999999">)</span> <span style="color:#98c379">18</span>
- redis <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> flushdb
- OK
- redis <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> dbsize
- <span style="color:#999999">(</span><span style="color:#c678dd">integer</span><span style="color:#999999">)</span> <span style="color:#98c379">0</span>
- redis <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span>
- </code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
在本例中我们将0 号数据库中的key 都清除了。
- <span style="color:#000000"><code class="language-sql">flushall
- </code></span>
- 1
删除所有数据库中的所有key。
- <span style="color:#000000"><code class="language-sql">redis <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#999999">[</span><span style="color:#98c379">1</span><span style="color:#999999">]</span><span style="color:#669900">></span> dbsize
- <span style="color:#999999">(</span><span style="color:#c678dd">integer</span><span style="color:#999999">)</span> <span style="color:#98c379">1</span>
- redis <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#999999">[</span><span style="color:#98c379">1</span><span style="color:#999999">]</span><span style="color:#669900">></span> <span style="color:#c678dd">select</span> <span style="color:#98c379">0</span>
- OK
- redis <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> flushall
- OK
- redis <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#669900">></span> <span style="color:#c678dd">select</span> <span style="color:#98c379">1</span>
- OK
- redis <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#999999">[</span><span style="color:#98c379">1</span><span style="color:#999999">]</span><span style="color:#669900">></span> dbsize
- <span style="color:#999999">(</span><span style="color:#c678dd">integer</span><span style="color:#999999">)</span> <span style="color:#98c379">0</span>
- redis <span style="color:#98c379">127.0</span><span style="color:#98c379">.0</span><span style="color:#98c379">.1</span>:<span style="color:#98c379">6379</span><span style="color:#999999">[</span><span style="color:#98c379">1</span><span style="color:#999999">]</span><span style="color:#669900">></span>
- </code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
在本例中我们先查看了一个1 号数据库中有一个key,然后我切换到0 号库执行flushall 命令,结果1 号库中的key 也被清除了,说是此命令工作正常。
十一、持久化
Redis的高性能是由于其将所有数据都存储在了内存中,为了使Redis在重启之后仍能保证数据不丢失,需要将数据从内存中同步到硬盘中,这一过程就是持久化。
Redis支持两种方式的持久化,一种是RDB方式,一种是AOF方式。可以单独使用其中一种或将二者结合使用。
11.1、RDB持久化
RDB方式的持久化是通过快照(snapshotting)完成的,当符合一定条件时Redis会自动将内存中的数据进行快照并持久化到硬盘。
RDB是Redis默认采用的持久化方式,在redis.conf配置文件中默认有此下配置:
- <span style="color:#000000"><code class="language-sql"><span style="color:#c678dd">save</span> <span style="color:#98c379">900</span> <span style="color:#98c379">1</span>
- <span style="color:#c678dd">save</span> <span style="color:#98c379">300</span> <span style="color:#98c379">10</span>
- <span style="color:#c678dd">save</span> <span style="color:#98c379">60</span> <span style="color:#98c379">10000</span>
- </code></span>
- 1
- 2
- 3
save 开头的一行就是持久化配置,可以配置多个条件(每行配置一个条件),每个条件之间是“或”的关系,“save 900 1”表示15分钟(900秒钟)内至少1个键被更改则进行快照,“save 300 10”表示5分钟(300秒)内至少10个键被更改则进行快照。
在redis.conf中:
配置dir指定rdb快照文件的位置
配置dbfilenam指定rdb快照文件的名称
Redis启动后会读取RDB快照文件,将数据从硬盘载入到内存。根据数据量大小与结构和服务器性能不同,这个时间也不同。通常将记录一千万个字符串类型键、大小为1GB的快照文件载入到内存中需要花费20~30秒钟。
问题总结:
通过RDB方式实现持久化,一旦Redis异常退出,就会丢失最后一次快照以后更改的所有数据。这就需要开发者根据具体的应用场合,通过组合设置自动快照条件的方式来将可能发生的数据损失控制在能够接受的范围。如果数据很重要以至于无法承受任何损失,则可以考虑使用AOF方式进行持久化。
11.2、AOF持久化
默认情况下Redis没有开启AOF(append only file)方式的持久化,可以通过appendonly参数开启:
- <span style="color:#000000"><code class="language-sql">appendonly yes
- </code></span>
- 1
开启AOF持久化后每执行一条会更改Redis中的数据的命令,Redis就会将该命令写入硬盘中的AOF文件。AOF文件的保存位置和RDB文件的位置相同,都是通过dir参数设置的,默认的文件名是appendonly.aof,可以通过appendfilename参数修改:appendfilename appendonly.aof
十二、主从复制
12.1 什么是主从复制
持久化保证了即使redis服务重启也会丢失数据,因为redis服务重启后会将硬盘上持久化的数据恢复到内存中,但是当redis服务器的硬盘损坏了可能会导致数据丢失,如果通过redis的主从复制机制就可以避免这种单点故障,如下图:
说明:
- 主redis中的数据有两个副本(replication)即从redis1和从redis2,即使一台redis服务器宕机其它两台redis服务也可以继续提供服务。
- 主redis中的数据和从redis上的数据保持实时同步,当主redis写入数据时通过主从复制机制会复制到两个从redis服务上。
- 只有一个主redis,可以有多个从redis。
- 主从复制不会阻塞master,在同步数据时,master 可以继续处理client 请求
- 一个redis可以即是主又是从,如下图:
12.2 主从配置
主redis配置
无需特殊配置。
从redis配置
修改从redis服务器上的redis.conf文件,添加slaveof 主redisip 主redis端口
上边的配置说明当前该从redis服务器所对应的主redis是192.168.101.3,端口是6379
12.3 主从复制过程
12.3.1、完整复制
在redis2.8版本之前主从复制过程如下图:
复制过程说明:
1、slave 服务启动,slave 会建立和master 的连接,发送sync 命令。
2、master启动一个后台进程将数据库快照保存到RDB文件中
注意:此时如果生成RDB文件过程中存在写数据操作会导致RDB文件和当前主redis数据不一致,所以此时master 主进程会开始收集写命令并缓存起来。
3、master 就发送RDB文件给slave
4、slave 将文件保存到磁盘上,然后加载到内存恢复
5、master把缓存的命令转发给slave
注意:后续master 收到的写命令都会通过开始建立的连接发送给slave。
当master 和slave 的连接断开时slave 可以自动重新建立连接。如果master 同时收到多个slave 发来的同步连接命令,只会启动一个进程来写数据库镜像,然后发送给所有slave。
完整复制的问题:
在redis2.8之前从redis每次同步都会从主redis中复制全部的数据,如果从redis是新创建的从主redis中复制全部的数据这是没有问题的,但是,如果当从redis停止运行,再启动时可能只有少部分数据和主redis不同步,此时启动redis仍然会从主redis复制全部数据,这样的性能肯定没有只复制那一小部分不同步的数据高。
12.3.2、部分复制
部分复制说明:
从机连接主机后,会主动发起 PSYNC 命令,从机会提供 master的runid(机器标识,随机生成的一个串) 和 offset(数据偏移量,如果offset主从不一致则说明数据不同步),主机验证 runid 和 offset 是否有效, runid 相当于主机身份验证码,用来验证从机上一次连接的主机,如果runid验证未通过则,则进行全同步,如果验证通过则说明曾经同步过,根据offset同步部分数据。
十三 Redis事物
13.1 介绍
Redis事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断,Redis事务的主要作用就是串联多个命令防止别的命令插队。
13.2 Multi、Exec、discard
从输入Multi命令开始,输入的命令都会依次进入命令队列中,但不会执行,直到输入Exec后,Redis会将之前的命令队列中的命令依次执行。组队的过程中可以通过discard命令来放弃组队。
13.3 事务的错误处理
组队中某个命令出现了报告错误,执行时整个的所有队列会都会被取消。
执行阶段某个命令报出了错误,则只有报错的命令不会被执行,而其他的命令都会执行,不会回滚。
13.4 为什么要做成事务
场景:
你的账户里有10000块钱,有三人有你的账户,同时去参加双十一抢购:
一个请求想给金额减8000
一个请求想给金额减5000
一个请求想给金额减1000
Redis事物锁
悲观锁
顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。
乐观锁
顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。乐观锁适用于多读的应用类型,这样可以提高吞吐量。Redis就是利用这种check-and-set机制实现事务的。
有了版本控制,每次执行操作的时候,都先查询版本,版本不连续的话,再去查redis里的数据和版本,查完之后,版本连续的话再继续做下一步的"增删更新"等操作;
即关系型数据库一般采用的是悲观锁,而非关系型数据库使用的是乐观锁
13.5 redis事物的具体实现
语法
- <span style="color:#000000"><code class="language-shell">WATCH key <span style="color:#999999">[</span>key <span style="color:#999999">..</span>.<span style="color:#999999">]</span>
- </code></span>
- 1
在执行multi之前,先执行watch key1 [key2],可以监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。
取消锁
unwatch命令
-
取消 WATCH 命令对所有 key 的监视。
-
如果在执行 WATCH命令之后, EXEC命令或 DISCARD命令先被执行了的话,那么就不需要再执行 UNWATCH了。
13.6 redis事物三个特性
单独的隔离操作
事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。
没有隔离级别的概念
队列中的命令没有提交之前都不会实际的被执行,因为事务提交前任何指令都不会被实际执行,也就不存在“事务内的查询要看到事务里的更新,在事务外查询不能看到”这个让人万分头痛的问题 。
不保证原子性
Redis同一个事务中如果有一条命令执行失败,其后的命令仍然会被执行,没有回滚 。
十四 主从复制的搭建
14.1 什么是主从复制
介绍
主从复制,就是主机数据更新后根据配置和策略,自动同步到备机的master/slaver机制,Master以写为主,Slave以读为主,一个主机可以有多个从机,一个从机只能有一个主机;
优势
-
读写分离,性能扩展
-
容灾快速恢复
14.2 配置主从复制
配置从机即可,不需要配置主机(下边的才操作都是在从机里进行的配置,主机不用动)
- 拷贝多个redis.conf文件include(include指的是包含redis.conf里之前的配置)
- <span style="color:#000000"><code class="language-shell"><span style="color:#5c6370"># 新建redis6379.conf文件</span>
- vim redis6379.conf
- </code></span>
- 1
- 2
在新建的文件里写入如下内容
- <span style="color:#000000"><code class="language-shell"><span style="color:#5c6370"># 包含之前的配置信息:redis.conf</span>
- include /root/myredis/redis.conf
- </code></span>
- 1
- 2
- 开启daemonize yes
开启守护进程(后台运行),如果include后的redis.conf文件里已经开启了,则新建的redis6379.conf文件里就不用再开启了;
- Pid文件名字pidfile
- <span style="color:#000000"><code class="language-shell"><span style="color:#5c6370"># 从redis.conf里复制即可</span>
- pidfile /var/run/redis_6379.pid
- </code></span>
- 1
- 2
- 指定端口port
- <span style="color:#000000"><code class="language-shell">port 6379
- </code></span>
- 1
- Log文件名字
主机里配置过了的话,这里就不用再配置了
-
Dump.rdb名字改为自己的名字
- <span style="color:#000000"><code>dbfilename dump6379.rdb
- </code></span>
- 1
-
Appendonly 关掉或者换名字
主机里配置过了的话,这里就不用再配置了
配置完成后的redis6379.conf文件如下:
- <span style="color:#000000"><code class="language-shell">include /root/myredis/redis.conf
- pidfile /var/run/redis_6379.pid
- port 6379
- dbfilename dump6379.rdb
- </code></span>
- 1
- 2
- 3
- 4
然后在多台从机里配置上边的文件(记得改端口号)
打印主从复制的相关信息
- <span style="color:#000000"><code class="language-shell"><span style="color:#5c6370"># 启动redis,进入客户端后(redis-cli -p 6379)执行如下命令,查看当前机器是主还是从</span>
- info replication
- </code></span>
- 1
- 2
配置当前从机的主机信息
- <span style="color:#000000"><code># 配置主机的地址端口信息
- slaveof ip port
- </code></span>
- 1
- 2
此时,主机里写入信息后,从机就可以查到了,从机只能获取信息,不可以写入信息;
主机宕机
这种情况下,一旦主机宕机的话,就没有可以写入信息的redis机器了(从机不可以自动上位为主机),从机执行info replication命令,也可以查看主机状态:
此时,主机恢复正常以后:
主机恢复后,从机依然可以获取到主机宕机前的数据;
从机宕机
从机宕机,再恢复后,还得重新找一下主机,即需要重新执行slaveof ip port命令来找主机;
14.3 主从复制总结
-
切入点问题:slave1、slave2是从头开始复制还是从切入点开始复制?比如从k4进来,那之前的123是否也可以复制
从头开始复制,不是从切入点开始;
-
从机是否可以写?set可否?
不可以
- 主机shutdown后情况如何?从机是上位还是原地待命
原地待命
- 主机又回来了后,主机新增记录,从机还能否顺利复制?
可以顺利复制
- 其中一台从机down后重启后情况如何?依照原有它能跟上大部队吗?
不可以跟上大部队,只能重新找主机,然后再复制主机里的信息;
复制原理
-
每次从机联通后,都会给主机发送sync指令
-
主机立刻进行存盘操作,发送RDB文件,给从机
-
从机收到RDB文件后,进行全盘加载
-
之后每次主机的写操作,都会立刻发送给从机,从机执行相同的命令
14.4 哨兵模式
假如主机宕机,哨兵检测到后,根据投票数自动将从机转换为主机
配置哨兵
自定义的/myredis目录下新建sentinel.conf文件,在配置文件中填写内容:
- <span style="color:#000000"><code class="language-shell"><span style="color:#5c6370">#127.0.0.1 6379指的是当前主机的信息(还没宕机的主机) 1指的是主机宕机的话,至少有一台机器同意,则将从机变为主机</span>
- sentinel monitor mymaster 127.0.0.1 6379 1
- </code></span>
- 1
- 2
配置从机变成为主机的优先级
在从机配置文件redis_6381.conf里进行配置
- <span style="color:#000000"><code class="language-shell"><span style="color:#5c6370"># 主机宕机后,当前从机成为主机的优先级,值越小,优先级越高</span>
- slave-priority 10
- </code></span>
- 1
- 2
启动哨兵
执行redis-sentinel /myredis/sentinel.conf
此时,主机宕机的话,会根据优先级将从机自动生成新主机,并且其他从机立刻自动将新主机作为主机
选择新主机的条件
-
选择优先级靠前的:优先级配置在redis.conf中slave-priority 100
-
选择偏移量最大的:偏移量是指获得原主数据最多的
-
选择runid最小的从服务:每个redis实例启动后都会随机生成一个40位的runid
挑选出新的主服务之后,sentinel 向原主服务的从服务发送 slaveof 新主服务 的命令,复制新master;
当已下线的服务重新上线时,sentinel会向其发送slaveof命令,让其成为新主的从;
十五 redis集群
15.1 redis集群介绍
问题
容量不够,redis如何进行扩容?
并发写操作, redis如何分摊?
分布式与集群
如果一个项目里有多个信息:用户信息、订单信息、商品信息
分布式:
将用户信息、订单信息、商品信息分别存储在三台机器上(每台机器放不一样的内容)
集群:
将每一个信息平均分成三份,再将三份信息分别放在三台机器里
什么是redis集群
Redis 集群实现了对Redis的水平扩容,即启动N个redis节点,将整个数据库分布存储在这N个节点中,每个节点存储总数据的1/N。
Redis 集群通过分区(partition)来提供一定程度的可用性(availability): 即使集群中有一部分节点失效或者无法进行通讯, 集群也可以继续处理命令请求。
15.2 搭建redis集群
安装ruby环境
注意:安装ruby之前,要把前边配置的rdb文件删除,不然会有很多问题出现
- <span style="color:#000000"><code class="language-shell">yum <span style="color:#61aeee">install</span> ruby<span style="color:#999999">;</span>
- yum <span style="color:#61aeee">install</span> rubygems<span style="color:#999999">;</span>
- </code></span>
- 1
- 2
下载redis-3.2.0.gem
打开一遍的网址:https://rubygems.org/gems/redis/versions/
进入3.2.0版本后,点击右下角的下载即可
安装redis-3.2.0.gem
- <span style="color:#000000"><code class="language-shell"><span style="color:#5c6370"># 将上边下载下来的文件复制到/opt目录,然后执行下边的命令进行安装</span>
- gem <span style="color:#61aeee">install</span> --local redis-3.2.0.gem
- </code></span>
- 1
- 2
制作六个redis实例(用来模拟集群)
端口分别是6379、6380、6381、6389、6390、6391,其中6389是6379的从机,8390是6380的从机,6391是6381的从机,然后参考14.2章节进行配置
安装redis cluster配置修改
vim redis6379.conf
- <span style="color:#000000"><code># 在配置文件里打开集群模式
- cluster-enabled yes
- # 设定节点配置文件名
- cluster-config-file nodes-6379.conf
- # 设定节点失联时间,超过该时间(毫秒),集群自动进行主从切换。
- cluster-node-timeout 15000
- </code></span>
- 1
- 2
- 3
- 4
- 5
- 6
然后将redis6379.conf文件复制六份即可(内容记得做相应的修改,6379的地方都改为自己的端口号)
将六个节点合成一个集群
组合之前,请确保所有redis实例启动后,nodes-xxxx.conf文件都生成正常(即所有实例启动后,会生成各自对应的nodes-xxxx.conf文件)。
进入到redis解压后的目录的src里
- <span style="color:#000000"><code>cd /opt/redis-3.2.5/src
- </code></span>
- 1
执行如下命令
- <span style="color:#000000"><code># 切记:此处使用真实ip,不可以使用127.0.0.1
- ./redis-trib.rb create --replicas 1 192.168.1.100:6379 192.168.1.100:6380 192.168.1.100:6381 192.168.1.100:6389 192.168.1.100:6390 192.168.1.100:6391
- </code></span>
- 1
- 2
输入yes后:
15.3 查看集群信息
进入6379机器
- <span style="color:#000000"><code class="language-shell">redis-cli -p 6379
- </code></span>
- 1
执行如下命令查看集群信息
- <span style="color:#000000"><code>cluster nodes
- </code></span>
- 1
此时,在6379上写入数据,会有如下提示
MOVED 12706 192.168.1.100:6381
提示需要移动到6381机器上进行操作,这是因为redis一共16384个插槽,通过计算我们要插入的key的hash值(上边的截图可以看出来,计算后的key的hash值是12706),会将对应的值插入相应的插槽里
我们登陆的是6379机器,遇到上边的情况,本来会自动将数据插入到6381机器里,但是因为我们进入redis的方式不对,所以会出现MOVED 12706 192.168.1.100:6381提示
正确进入6379(集群)的方式:
- <span style="color:#000000"><code class="language-shell"><span style="color:#5c6370"># -c:自动重定向 -p:端口</span>
- redis-cli -c -p 6379
- </code></span>
- 1
- 2
可以看到,自动切换到6381机器了;
15.4 redis cluster 如何分配这六个节点
-
一个集群至少要有三个主节点
-
选项 --replicas 1 表示我们希望为集群中的每个主节点创建一个从节点。
-
分配原则尽量保证每个主数据库运行在不同的IP地址,每个从库和主库不在一个IP地址上。
15.5 slots插槽
-
一个 Redis 集群包含 16384 个插槽(hash slot), 数据库中的每个键都属于这 16384 个插槽的其中一个, 集群使用公式 CRC16(key) % 16384 来计算键 key 属于哪个槽, 其中 CRC16(key) 语句用于计算键 key 的 CRC16 校验和 。
-
集群中的每个节点负责处理一部分插槽。 举个例子, 如果一个集群可以有主节点, 其中:
节点 A 负责处理 0 号至 5500 号插槽。
节点 B 负责处理 5501 号至 11000 号插槽。
节点 C 负责处理 11001 号至 16383 号插槽。
在集群中录入值
在redis-cli每次录入、查询键值,redis都会计算出该key应该送往的插槽,如果不是该客户端对应服务器的插槽,redis会报错,并告知应前往的redis实例地址和端口。
redis-cli客户端提供了 –c 参数实现自动重定向。如 redis-cli -c –p 6379 登入后,再录入、查询键值对可以自动重定向。
不在一个slot下的键值,是不能使用mget,mset等多键操作。
可以通过{}来定义组的概念,从而使key中{}内相同内容的键值对放到一个slot中去。
查询集群中的值
CLUSTER KEYSLOT 计算键 key 应该被放置在哪个槽上。
CLUSTER COUNTKEYSINSLOT 返回槽 slot 目前包含的键值对数量。
CLUSTER GETKEYSINSLOT 返回 count 个 slot 槽中的键。
15.6 故障恢复
•如果主节点下线?从节点能否自动升为主节点?
•主节点恢复后,主从关系会如何?
•如果所有某一段插槽的主从节点都宕掉,redis服务是否还能继续?
•redis.conf中的参数 cluster-require-full-coverage
配置故障恢复参数
- <span style="color:#000000"><code class="language-shell"><span style="color:#5c6370"># redis.conf中的参数 </span>
- cluster-require-full-coverage
- </code></span>
- 1
- 2
15.7 集群的Jedis开发
- <span style="color:#000000"><code class="language-java"><span style="color:#c678dd">public</span> <span style="color:#c678dd">class</span> JedisClusterTest <span style="color:#999999">{</span>
-
-
-
- <span style="color:#c678dd">public</span> <span style="color:#c678dd">static</span> <span style="color:#c678dd">void</span> <span style="color:#61aeee">main</span><span style="color:#999999">(</span>String<span style="color:#999999">[</span><span style="color:#999999">]</span> args <span style="color:#999999">)</span> <span style="color:#999999">{</span>
-
- Set<span style="color:#61aeee"><span style="color:#999999"><</span>HostAndPort<span style="color:#999999">></span></span> set <span style="color:#669900">=</span><span style="color:#c678dd">new</span> HashSet<span style="color:#61aeee"><span style="color:#999999"><</span>HostAndPort<span style="color:#999999">></span></span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
-
- set<span style="color:#999999">.</span><span style="color:#61aeee">add</span><span style="color:#999999">(</span><span style="color:#c678dd">new</span> HostAndPort<span style="color:#999999">(</span><span style="color:#669900">"192.168.1.100"</span><span style="color:#999999">,</span><span style="color:#98c379">6379</span><span style="color:#999999">)</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
- set<span style="color:#999999">.</span><span style="color:#61aeee">add</span><span style="color:#999999">(</span><span style="color:#c678dd">new</span> HostAndPort<span style="color:#999999">(</span><span style="color:#669900">"192.168.1.100"</span><span style="color:#999999">,</span><span style="color:#98c379">6380</span><span style="color:#999999">)</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
- set<span style="color:#999999">.</span><span style="color:#61aeee">add</span><span style="color:#999999">(</span><span style="color:#c678dd">new</span> HostAndPort<span style="color:#999999">(</span><span style="color:#669900">"192.168.1.100"</span><span style="color:#999999">,</span><span style="color:#98c379">6381</span><span style="color:#999999">)</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
- set<span style="color:#999999">.</span><span style="color:#61aeee">add</span><span style="color:#999999">(</span><span style="color:#c678dd">new</span> HostAndPort<span style="color:#999999">(</span><span style="color:#669900">"192.168.1.100"</span><span style="color:#999999">,</span><span style="color:#98c379">6389</span><span style="color:#999999">)</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
- set<span style="color:#999999">.</span><span style="color:#61aeee">add</span><span style="color:#999999">(</span><span style="color:#c678dd">new</span> HostAndPort<span style="color:#999999">(</span><span style="color:#669900">"192.168.1.100"</span><span style="color:#999999">,</span><span style="color:#98c379">6390</span><span style="color:#999999">)</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
- set<span style="color:#999999">.</span><span style="color:#61aeee">add</span><span style="color:#999999">(</span><span style="color:#c678dd">new</span> HostAndPort<span style="color:#999999">(</span><span style="color:#669900">"192.168.1.100"</span><span style="color:#999999">,</span><span style="color:#98c379">6391</span><span style="color:#999999">)</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
- <span style="color:#5c6370">//注意:这里new的是集群JedisCluster</span>
- JedisCluster jedisCluster<span style="color:#669900">=</span><span style="color:#c678dd">new</span> JedisCluster<span style="color:#999999">(</span>set<span style="color:#999999">)</span><span style="color:#999999">;</span>
-
- jedisCluster<span style="color:#999999">.</span><span style="color:#61aeee">set</span><span style="color:#999999">(</span><span style="color:#669900">"k1"</span><span style="color:#999999">,</span> <span style="color:#669900">"v1"</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
- System<span style="color:#999999">.</span>out<span style="color:#999999">.</span><span style="color:#61aeee">println</span><span style="color:#999999">(</span>jedisCluster<span style="color:#999999">.</span><span style="color:#61aeee">get</span><span style="color:#999999">(</span><span style="color:#669900">"k1"</span><span style="color:#999999">)</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
- <span style="color:#999999">}</span>
- <span style="color:#999999">}</span>
- </code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
15.8 总结
集群优势
-
实现扩容
-
分摊压力
-
无中心配置相对简单
集群不足
-
多键操作是不被支持的
-
多键的Redis事务是不被支持的。lua脚本不被支持。
-
由于集群方案出现较晚,很多公司已经采用了其他的集群方案,而代理或者客户端分片的方案想要迁移至redis cluster,需要整体迁移而不是逐步过渡,复杂度较大。
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/正经夜光杯/article/detail/826984推荐阅读
相关标签Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。