一.redis介绍与安装使用
1.redis安装
1.1redis是C语言开发,建议在linux上运行,编译依赖gcc环境,如果没有gcc环境,需要安装gcc:yum install gcc-c++
1.2从官网下载 http://download.redis.io/releases/redis-3.0.0.tar.gz将redis-3.0.0.tar.gz拷贝到/usr/local下
1.3解压源码 tar -zxvf redis-3.0.0.tar.gz
1.4进入解压后的目录进行编译 cd /usr/local/redis-3.0.0 make
1.5安装到指定目录,如 /usr/local/redis
cd /usr/local/redis-3.0.0
make PREFIX=/usr/local/redis install
1.6 redis.conf是redis的配置文件,redis.conf在redis源码目录。
注意修改port作为redis进程的端口,port默认6379。
1,.7进入源码目录,里面有一份配置文件 redis.conf,然后将其拷贝到安装路径下
cd /usr/local/redis
mkdir conf
cp /usr/local/redis-3.0.0/redis.conf /usr/local/redis/bin
1.8后端模式启动 前端模式启动,会随着SSH关闭而结束;
修改redis.conf配置文件, daemonize yes 以后端模式启动。 执行如下命令启动redis: cd /usr/local/redis ./bin/redis-server ./redis.conf redis默认使用6379端口。
1.9 启动多个redis进程
创建多个redis目录,以端口号命名,比如:创建6379、6380两个目录,将redis的安装文件bin和conf拷贝至这两个目录。 修改6379目录下的redis.conf设置端口号为6379 修改6380目录下的redis.conf设置端口号为6380 启动6379和6380目录下的redis-server程序: cd 6379 ./redis-server . /redis.conf cd 6380 ./redis-server . /redis.conf
2.0启动客服端链接服务器端,之前要将redis启动,且配置号本机IP地址和端口号
./redis-cli -h127.0.23.1 -P 6079 也可在配置文件配置号,直接启动
二.使用
1.基本命令
1.1Redis提供了PING命令来测试客户端与Redis的连接是否正常,如果连接正常会收到回复PONG
1.2使用set和get可以向redis设置数据、获取数据
1.3递增/递减数字
INCR/DECR key
当存储的字符串是整数时,Redis提供了一个实用的命令INCR/DECR,其作用是让当前键值递增,并返回递增后的值。
127.0.0.1:6379> incr/decr num
(integer) 1
127.0.0.1:6379> incr/decr num
(integer) 2
1.4向尾部追加值
APPEND key value
APPEND的作用是向键值的末尾追加value。如果键不存在则将该键的值设置为value,即相当于 SET key value。返回值是追加后字符串的总长度。
127.0.0.1:6379> set str hello
OK
127.0.0.1:6379> append str " world!"
(integer) 12
1.5 获取字符串长度
STRLEN key
STRLEN命令返回键值的长度,如果键不存在则返回0。
127.0.0.1:6379> strlen str
(integer) 0
127.0.0.1:6379> set str hello
OK
127.0.0.1:6379> strlen str
(integer) 5
1.6同时设置/获取多个键值
MSET key value [key value …]
MGET key [key …]
127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3
OK
127.0.0.1:6379> get k1
"v1"
127.0.0.1:6379> mget k1 k3
1) "v1"
2) "v3"
1.7设置key的生存时间
Redis在实际使用过程中更多的用作缓存,然而缓存的数据一般都是需要设置生存时间的,即:到期后数据销毁。
EXPIRE key seconds
设置key的生存时间(单位:秒)key在多少秒后会自动删除
TTL key
查看key生于的生存时间
PERSIST key
清除生存时间
PEXPIRE key milliseconds
生存时间设置单位为:毫秒
例子:
192.168.101.3:7002> set test 1
设置test的值为1
OK
192.168.101.3:7002> get test
获取test的值
"1"
192.168.101.3:7002> EXPIRE test 5
设置test的生存时间为5秒
2.单实例连接redis
@Test
public void testJedisSingle() {
Jedis jedis = new Jedis("192.168.101.3", 6379);
jedis.set("name", "bar");
String name = jedis.get("name");
System.out.println(name);
jedis.close();
}
3.使用连接池链通过 单实例连接redis不能对redis连接进行共享,可以使用连接池对redis连接进行共享,提高资源利用率,使用jedisPool连接redis服务,如下代码:
@Test
public void pool() {
JedisPoolConfig config = new JedisPoolConfig();
//最大连接数
config.setMaxTotal(30);
//最大连接空闲数
config.setMaxIdle(2);
JedisPool pool = new JedisPool(config, "192.168.101.3", 6379);
Jedis jedis = null;
try {
jedis = pool.getResource();
jedis.set("name", "lisi");
String name = jedis.get("name");
System.out.println(name);
}catch(Exception ex){
ex.printStackTrace();
}finally{
if(jedis != null){
//关闭连接
jedis.close();
}
}
}
4.与spring联合使用
l配置spring配置文件applicationContext.xml
<!-- 连接池配置 -->
<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 index="0" ref="jedisPoolConfig"></constructor-arg>
<constructor-arg index="1" value="192.168.101.3"></constructor-arg>
<constructor-arg index="2" value="7001"></constructor-arg>
</bean>
测试代码:
private ApplicationContext applicationContext;
@Before
public void init() {
applicationContext = new ClassPathXmlApplicationContext(
"classpath:applicationContext.xml");
}
@Test
public void testJedisPool() {
JedisPool pool = (JedisPool) applicationContext.getBean("jedisPool");
try {
jedis = pool.getResource();
jedis.set("name", "lisi");
String name = jedis.get("name");
System.out.println(name);
}catch(Exception ex){
ex.printStackTrace();
}finally{
if(jedis != null){
//关闭连接
jedis.close();
}
}
}
5.hash问题 使用string的问题
假设有User对象以JSON序列化的形式存储到Redis中,User对象有id,username、password、age、name等属性,存储的过程如下:
保存、更新:
User对象 à json(string) à redis
如果在业务上只是更新age属性,其他的属性并不做更新我应该怎么做呢? 如果仍然采用上边的方法在传输、处理时会造成资源浪费,下边讲的hash可以很好的解决这个问题
5.1
赋值与取值
HSET key field value
一次只能设置一个字段值
HGET key field
一次只能获取一个字段值
HMSET key field value [field value ...]
一次可以设置多个字段值
HMGET key field [field ...]
一次可以获取多个字段值
HGETALL key
127.0.0.1:6379> hset user username zhangsan
(integer) 1
127.0.0.1:6379> hget user username
"zhangsan“
HSET命令不区分插入和更新操作,当执行插入操作时HSET命令返回1,当执行更新操作时返回0.
127.0.0.1:6379> hmset user age 20 username lisi
OK
127.0.0.1:6379> hmget user age username
1) "20"
2) "lisi"
127.0.0.1:6379> hgetall user
1) "age"
2) "20"
3) "username"
4) "lisi"
5.2判断字段是否存在
HEXISTS key field
127.0.0.1:6379> hexists user age
查看user中是否有age字段
(integer) 1
127.0.0.1:6379> hexists user name
查看user中是否有name字段
(integer) 0
HSETNX key field value
当字段不存在时赋值,类似HSET,区别在于如果字段已经存在,该命令不执行任何操作。
127.0.0.1:6379> hsetnx user age 30
如果user中没有age字段则设置age值为30,否则不做任何操作
(integer) 0
5.3只获取字段名或字段值
HKEYS key
HVALS key
127.0.0.1:6379> hmset user age 20 name lisi
OK
127.0.0.1:6379> hkeys user
1) "age"
2) "name"
127.0.0.1:6379> hvals user
1) "20"
2) "lisi"
5.4获取字段数量
HLEN key
127.0.0.1:6379> hlen user
(integer) 2
5.5实例
商品id、商品名称、商品描述、商品库存、商品好评
定义商品信息的key:
商品1001的信息在 redis中的key为:items:1001
存储商品信息
192.168.101.3:7003> HMSET items:1001 id 3 name apple price 999.9
OK
获取商品信息
192.168.101.3:7003> HGET items:1001 id
"3"
192.168.101.3:7003> HGETALL items:1001
1) "id"
2) "3"
3) "name"
4) "apple"
5) "price"
6) "999.9
"
6.有序集合和列表
在某些方面有序集合和列表类型有些相似。
1、二者都是有序的。
2、二者都可以获得某一范围的元素。
但是,二者有着很大区别:
1、列表类型是通过链表实现的,获取靠近两端的数据速度极快,而当元素增多后,访问中间数据的速度会变慢。
2、有序集合类型使用散列表实现,所有即使读取位于中间部分的数据也很快。
3、列表中不能简单的调整某个元素的位置,但是有序集合可以(通过更改分数实现)
4、有序集合要比列表类型更耗内存。