redis 是一个开源的、使用 C 语言编写的、支持网络交互的、可基于内存也可持久 化的 Key-Value 数据库。redis 数据结构:redis 是一种高级的 key:value 存储系统,其中 value 支持五种数据类型:
1.字符串(strings)
2.字符串列表(lists)
3.字符串集合(sets)
4.有序字符串集合(sorted sets)
5.哈希(hashes)
Redis 适用场景:
1.缓存——热数据:热点数据(经常会被查询,但是不经常被修改或者删除的数据), 首选是使用 redis 缓存。
2.计数器:诸如统计点击数等应用。由于单线程,可以避免并发问题,保证不会出错,而且 100%毫秒级性能!
3.排行榜:谁得分高谁排名往上。命令:ZADD(有续集,sorted set)
4.最新列表:例如新闻列表最新页面,总数量很大的情况下,尝试 redis 的 LPUSH 命令构建 List,一个个顺序都塞进去就可以
5.分布式锁与单线程机制:秒杀系统,基于 redis 是单线程特征,防止出现数据库 “爆破”
6.位操作(大数据处理):用于数据量上亿的场景下,例如几亿用户系统的签到, 去重登录次数统计,某用户是否在线等等。
7.队列:由于 redis 把数据添加到队列是返回添加元素在队列的第几位,所以可以做判 断用户是第几个访问这种业务。
Redis 数据库的安装
先在根目录下 安装redis编译的c环境: yum install gcc-c++
上传redis-3.0.0.tar.gz到linux系统;
解压到/usr/local 下 tar zxvf redis-3.0.0.tar.gz -C/usr/local
进入redis-3.0.0目录下,使用 make 命令编译 redis。(注意大写PREFIX)
在 redis-3.0.0 目录中 使用 make PREFIX=/usr/local/redis install 命令安装 redis 到/usr/local/redis 中 目录
拷贝 redis-3.0.0 中的 redis.conf 到安装目录 redis 中;
进入源码目录,里面有一份配置文件 redis.conf, cd /usr/local/redis然后将其拷贝到安装路径下:
cp /usr/local/redis-3.0.0/redis.conf /usr/local/redis/bin
redis.conf是redis的配置文件,redis.conf在redis源码目录。
注意port作为redis进程的端口,port默认6379。
前端模式下启动 redis: 在 bin 下执行命令 redis-server;
直接运行 bin/redis-server 将以前端模式启动,前端模式启动的缺点是 ssh 命令窗口关闭,则redis-server程序结束,不推荐使用此方法。推荐后端模式的启动!
后端模式启动:修改redis.conf文件,daemonize 把no 改为 yes 后端模式启动
修改权限 chmod 777 redis.conf
(chomd777,每个人都有读写和执行的权限,root账号登录的不需要此操作!
修改redis.conf配置文件 vi /usr/local/redis/bin/redis.conf
使用命令 :set nu出现序号
使用命令 /daemonize (daemonize表示你想要搜索内容,相当于 window 的 Ctrl+f),按回车键后,点击 n 查找下一个
保存后退出 :wq 相当于 :x
启动redis:cd /usr/local/redis/bin ./redis-server redis.conf
查看是否启动:ps aux | grep redis
查看进程命令:ps -ef | grep redis
打开虚拟机中的防火墙对应的端口:6379;先关闭防火墙:service iptables stop (临时关闭)chkconfig iptables off(永久关闭).编辑iptables,增加6379端口 (做法跟添加mysql,tomcat的端口号相似!)
vi /etc/sysconfig/iptables
使用./redis-cli shutdown,redis 会先保存好数据,再关闭;
Kill -9 暴力关闭,可能会丢失数据。
在后台启动完redis-server,启动./redis-cli(客户端开启的命令),就可以获取到 get key1的内容了,redis 服务器就永远的启动了。
Java操作Redis数据库:(导入2个ja包,共享文件夹中)
commons-pool2-2.3.jar与jedis-2.7.0.jar
1 package cn.redis.util; 2 3 import redis.clients.jedis.Jedis; 4 import redis.clients.jedis.JedisPool; 5 import redis.clients.jedis.JedisPoolConfig; 6 7 /** 8 * redis连接池 9 */ 10 public class RedisPoolUtil { 11 12 /** 13 * redis连接池 14 * @return 15 */ 16 public static Jedis getRedis(){ 17 JedisPoolConfig jpc=new JedisPoolConfig(); 18 jpc.setMaxTotal(50);//最大的连接数量 19 jpc.setMaxIdle(5);//最大闲置连接数量 20 JedisPool jedisPool = new JedisPool("192.168.1.112", 6379); 21 return jedisPool.getResource();//返回jedis连接对象 22 } 23 24 }
1 package cn.redis.util; 2 3 import redis.clients.jedis.BinaryClient; 4 import redis.clients.jedis.Jedis; 5 6 import java.util.HashMap; 7 import java.util.List; 8 import java.util.Map; 9 import java.util.Set; 10 11 public class MyRedis { 12 13 /** 14 * 在centos中,打开客户端命令,进入redis/bin目录下,./redis-cli命令 15 * 退出服务器命令:./redis-cli shutdown,redis会先保存好数据后,安全的关闭 16 * 暴力关闭,可能会丢失数据 .kill -9 17 * @param args 18 */ 19 public static void main(String[] args) { 20 Jedis redis = RedisPoolUtil.getRedis(); 21 22 // test_redisString(redis);//测试redis字符串数据类型 23 24 // test_redisHash(redis);//Redis 的数据类型:哈希 hash; 25 26 // test_redisList(redis);//Redis 的数据类型:list 链表; 27 28 // test_redisSet(redis);//Redis 的数据类型:set(不充许重复元素); //适用场景:跟踪用户购买了哪些商品信息,求并集等。 29 30 test_redisSortedset(redis);//Redis 的数据类型:sortedset; 有序集合 //适用场景:积分排名表,排行榜等 31 } 32 33 /** 34 * edis 的数据类型:sortedset; 有序集合 35 * 适用场景:积分排名表,排行榜等 36 * @param redis 37 */ 38 private static void test_redisSortedset(Jedis redis) { 39 //添加多个元素,如果有相同的就会覆盖 40 Map<String, Double> map = new HashMap<>(); 41 map.put("内key4",63.9); 42 map.put("内key5",73.9); 43 map.put("内key6",103.9); 44 redis.zadd("sortedsetKey",map); 45 System.out.println("查看所有的内部key==>"+redis.zrange("sortedsetKey",0,-1)); 46 47 //查看内key2 的值 48 System.out.println(redis.zscore("sortedsetKey","内key2")); 49 50 //删除内key3 51 System.out.println(redis.zrem("sortedsetKey","内key2")); 52 53 //按照指定范围删除 54 redis.zremrangeByScore("sortedsetKey",0,55.5); 55 56 //查看总共有多少 57 System.out.println(redis.zcard("sortedsetKey")); 58 59 //按照指定方位查看 60 System.out.println(redis.zrangeByScore("sortedsetKey",0,1000)); 61 62 //加分 63 redis.zincrby("sortedsetKey",100,"内key2"); 64 System.out.println(redis.zscore("sortedsetKey","内key2")); 65 66 //指定范围内的个数 67 Long sortedsetKey = redis.zcount("sortedsetKey", 0, 40); 68 System.out.println(sortedsetKey); 69 70 //升序,查看指定的内key升序排名 71 System.out.println(redis.zrank("sortedsetKey","内key2")); 72 //降序,查看指定的内key降序排名 73 System.out.println(redis.zrevrank("sortedsetKey","内key2")); 74 75 } 76 77 /** 78 * Redis 的数据类型:set(不充许重复元素); 79 * 适用场景:跟踪用户购买了哪些商品信息,求并集等。 80 * 81 * @param redis 82 */ 83 private static void test_redisSet(Jedis redis) { 84 //sets数据类型添加数据 85 redis.sadd("setskey","values4","values5","values6"); 86 System.out.println(redis.smembers("setskey")); 87 88 //删除两个 89 redis.srem("setskey","values5","values1"); 90 System.out.println(redis.smembers("setskey")); 91 92 //查看是否存在指定元素 93 Boolean sismember = redis.sismember("setskey", "values1"); 94 System.out.println(sismember); 95 96 //插入数据到setskey2中 97 redis.sadd("setskey2","values6","values4","s2的值3"); 98 System.out.println(redis.smembers("setskey")); 99 System.out.println(redis.smembers("setskey2")); 100 //求差集,以setskey为基准 101 System.out.println(redis.sdiff("setskey","setskey2")); 102 //求差集,以ssetskey2为基准 103 System.out.println(redis.sdiff("setskey2","setskey")); 104 105 //求并集 106 System.out.println(redis.sunion("setskey2","setskey")); 107 108 //求交集 109 System.out.println(redis.sinter("setskey2","setskey")); 110 111 //查询元素个数 112 System.out.println(redis.scard("setskey2")); 113 114 //返回随机元素 115 System.out.println(redis.srandmember("setskey2")); 116 117 //setskey2与setskey的差集存储到s3中 118 System.out.println(redis.sdiffstore("s3","setskey2","setskey")); 119 System.out.println(redis.smembers("s3")); 120 121 //setskey2与setskey的交集存储到s4中 122 System.out.println(redis.sinterstore("s4","setskey2","setskey")); 123 System.out.println(redis.smembers("s4")); 124 125 //setskey2与setskey的并集存储到s5中 126 System.out.println(redis.sunionstore("s5","setskey2","setskey")); 127 System.out.println(redis.smembers("s5")); 128 } 129 130 /** 131 * Redis 的数据类型:list 链表; 132 * @param redis 133 */ 134 private static void test_redisList(Jedis redis) { 135 // 插入数据,,//从头部左边插入 136 redis.lpush("list链表", "value1", "value2", "value3", "value4"); 137 System.out.println("查看所有list链表中的数据"+redis.lrange("list链表",0,-1)); 138 139 //从尾部,右边插入 140 redis.rpush("list链表","右边vlaue1","右边vlaue2","右边vlaue3"); 141 System.out.println(redis.lrange("list链表",0,99)); 142 143 //判断是否可以插入 144 Long lpush = redis.lpush("list2", "可以插入"); 145 System.out.println(lpush); 146 //判断是否可以插入 147 Long lpushx = redis.lpushx("list3", "不可以插入"); 148 System.out.println(lpushx); 149 150 System.out.println(redis.lrange("list链表",0,-1)); 151 152 //从头部弹出一个 153 String list链表 = redis.lpop("list链表"); 154 System.out.println(list链表); 155 156 //从尾部弹出一个 157 String list链表1 = redis.rpop("list链表"); 158 System.out.println(list链表1); 159 160 //查看还剩下几个 161 Long list链表2 = redis.llen("list链表"); 162 System.out.println(list链表2); 163 164 //删除两个value2 165 redis.lrem("list链表",2,"value2"); 166 List<String> list链表3 = redis.lrange("list链表", 0, -1); 167 System.out.println(list链表3); 168 169 //删除所有的youbianvalue1 , 0表示删除所有 170 redis.lrem("list链表",0,"右边vlaue1"); 171 System.out.println(redis.lrange("list链表",0,-1)); 172 173 //负数表示从尾部开始删除,-1表示从尾部删除一个,-2表示删除两个 174 redis.lrem("list链表",-1,"右边vlaue1"); 175 System.out.println(redis.lrange("list链表",0,-1)); 176 177 //根据下标改变元素的值 178 redis.lset("list链表",0,"我是下标为0,改变了值"); 179 redis.lrange("list链表",0,-1).forEach(ls-> System.out.println(ls)); 180 181 //在aa后面插入bb 182 redis.linsert("list链表", BinaryClient.LIST_POSITION.AFTER,"value1","我是在value1后面插队的值"); 183 System.out.println(redis.lrange("list链表",0,-1)); 184 //在aa前面插入cc 185 redis.linsert("list链表", BinaryClient.LIST_POSITION.BEFORE,"value1","我是在value1前面插队的值"); 186 System.out.println(redis.lrange("list链表",0,-1)); 187 188 //新建list2 189 redis.lpush("list2","list2中的值1","list2中的值2","list2中的值3"); 190 //将list1的尾部元素弹出,并且压压到sit2头 191 redis.rpoplpush("list链表","list2"); 192 System.out.println("list1中的数据"+redis.lrange("list链表",0,-1)); 193 System.out.println("list2中的数据"+redis.lrange("list2",0,-1)); 194 } 195 196 /** 197 * Redis 的数据类型:哈希 hash; 198 * @param redis 199 */ 200 private static void test_redisHash(Jedis redis) { 201 //存一次 202 redis.hset("哈希用法外部key","内部key","内部value"); 203 System.out.println("拿到哈希中的内部的value===》"+redis.hget("哈希用法外部key","内部key")); 204 205 //村多个 206 Map<String, String> hash = new HashMap<>(); 207 hash.put("内部key1","内部value1"); 208 hash.put("内部key2","1"); 209 hash.put("内部key3","内部value3"); 210 redis.hmset("waikey",hash); 211 System.out.println(redis.hmget("waikey","内部key1","内部key2","内部key3")); 212 213 //一次删除两个 214 Long hdel = redis.hdel("waikey", "内部key1", "内部key2"); 215 System.out.println("返回删除的数量===》"+hdel); 216 //一次全部删除 217 Long waikey = redis.del("waikey"); 218 System.out.println(waikey); 219 System.out.println(redis.get("waikey")); 220 221 //查看删除后的map集合中的数据 222 System.out.println(redis.hmget("waikey","内部key1","内部key2","内部key3")); 223 224 //在原有的基础上加20 225 Long aLong = redis.hincrBy("数字", "age", 20); 226 System.out.println(aLong); 227 228 //判断是否存在,存在返回(true),否则返回(false) 229 Boolean hexists = redis.hexists("数字", "age"); 230 System.out.println(hexists); 231 232 //获取元素的个数 233 Long 数字 = redis.hlen("数字"); 234 System.out.println(数字); 235 236 //获取哈希中所有key 237 Set<String> ks = redis.hkeys("数字"); 238 ks.forEach(k-> System.out.print(k+" , ")); 239 240 System.out.println(); 241 242 //获取哈希中所有的value 243 List<String> vs = redis.hvals("数字"); 244 vs.forEach(v-> System.out.print(v+" , ")); 245 } 246 247 /** 248 * 测试redis字符串数据类型 249 */ 250 private static void test_redisString(Jedis redis) { 251 redis.set("这是key","通过key,拿到字符串值"); 252 System.out.println(redis.get("这是key")); 253 254 String k = redis.get("无value的key"); 255 System.out.println("没有定义value的key==》"+k);//返回为null 256 System.out.println("查看redis中所有的key集==》"+redis.keys("*")); 257 Long age = redis.incr("age"); 258 System.out.println(age);//自增1,如果没有,则返回为0(默认为0) 259 260 Long age1 = redis.decr("age"); 261 System.out.println(age1);//自减1,如果没有,则返回0,(默认为0) 262 263 Long append = redis.append("这是key", "==>进行追加的值");//字符串追加 264 String s = redis.get("这是key");//返回,使用append追加后的值 265 System.out.println(s); 266 267 redis.set("money","1000"); 268 String money = redis.get("money"); 269 System.out.println(money); 270 271 Long money1 = redis.incrBy("money", 200); 272 System.out.println("在原有的基础上再次增加200===》"+money1); 273 274 Long money2 = redis.decrBy("money", 1000); 275 System.out.println("在原有的基础上再次减少1000===》"+money2); 276 277 Long money3 = redis.del("money"); 278 System.out.println("删除key,如果有key则返回1,否则返回0==》"+money3); 279 280 } 281 282 }