Windows环境中的Redis的启动与测试
1、先启动Redis-server(redis安装目录下的redis-server.exe)
2、再启动Redis-cli客户端(redis-cli.exe)
3、就可以连接Redis服务器了(一般是6379端口)
NoSQL是Not-Only-SQL的缩写,是被设计用来替换传统的关系型数据库在某些领域使用,特别针对web2.0站点以及大型的SNS网站,用来满足高并发、大数据的应用需求。
常见的NoSQL数据库系统有HBase(Hadoop数据库,基于列存储)、MonGDB(文档型数据库,采用类型与JSON的BSON语法存储记录)、Redis/Memcached(键值存储数据库)等类型。
Redis是NoSQLogic系统数据库中,和Memcached最为相似的数据库系统,同属键值存储系统。严格意义上来讲,Memcached并不能算作数据库系统,只能算作中间缓存系统,
因为其并不能进行数据的持久化存储。Redis的字面意思是:远程字典服务器(REmote DIctionary Server),和Memcached相比较,提供了更加丰富的数据类型微笑,更被认为是一种数据结构服器。
和Memcached相比,Redis的优势十分明显。
1. 数据类型:Redis支持更丰富的数据类型,包括字符串(string)、列表(list:可用作队列、堆栈)、集合(set:可以进行集合的运算)、有序集合(sorted set)、哈希表(hash)等,而Memcached仅支持字符串。
2. 对象大小:Redis支持的对象大小最大支持1GB,而Memcached仅为1MB,仅从这个角度来讲,就很有使用Redis替换Memcached的必要。
3. 分片(Sharding):可以将数据离散地存储在不同的物理机器上,以克服单台机器的内存大小限制。Memcached是在服务器实现实现分片的,而Redis需要借助于Jedis实现客户端分片,Jedis是Redis官方推荐的使用Java访问Redis的方式。
使用Jedis的分片机制,存储一批数据,在不同的Redis服务器上存储着这批数据的不同部分.而这对客户端来说,而完全透明的,看不到这种差别。另外需要注意,使用Spring Data Redis进行客户端操作时,不提供对分片支持。
4. 持久化:Redis能够将添加到内存中的数据持久化到磁盘,而Memcached则只能充当一个功能相对有限的缓存中间件角色。
1. 数据库服务器:用来存储结构相对简单的的数据。
2. 缓存系统:缓存需要大量读取、少量修改的数据。
3. 构建实时消息系统:利用发布(Pub)/订阅(Sub)特性。
4. 对队列的支持:基于列表(list)实现队列(queue)、堆栈(stack)。
Redis提供了丰富的命令,允许我们连接客户端对其进行直接操作,这里简单介绍一下作为常用的一些命令,包括对字符串、 列表、集合、有序集合、哈希表的操作,以及一些其他常用命令
set name James
get name
set age 22;
incr age; // age变为23
decr age; // age变为21
setnx name Nick
setex name 5 Bill;
//上面的命令等价于
set name Bill;
expire name 5;
rpush userList James
lpop userList
lrange userList 0 -1
lset userList 1 "Wang Jie"
llen userList
ltrim userList 1 3
sadd fruit watermelon
sadd fruit apple pear
smembers fruit
srem fruit apple
scard fruit
sismember fruit pear
sunion food fruit
zadd user 23 James
zadd user 24 James
zrange user 0 -1
hset china shannxi xian
hget china shannxi
hkeys china
hvals china
flushdb
flushall
ping
quit
shutdown
requirepass WangJie; //在配置文件总全文搜素requirepass,将其取消注释,并修改后面的字符串(密码)
auth WangJie;
slaveof 192.168.142.12 6379
masterauth WangJie
bgsave //该命令在后台执行,进行持久化操作,不会影响客户端的链接
save //如果上述bgsave执行失败,可以使用save进行操作,但是会影响客户端的链接
mkdir -p /opt/redis/logs
mkdir -p /opt/redis/data
loglevel debug //日志级别:默认为notice
logfile /opt/redis/logs/redis.log //日志输出:默认为stdout
dbfilename redis.rdb //默认为dump.rdb
dir /opt/redis/data //默认为./
maxmemory 256mb
#@ 设置Redis能够占用的最大内存,防止影响性能甚至造成系统崩溃。
#@ 一定要小于物理内存(512MB),留有充足的内存供系统及其他应用程序使用。
save 60 1000
#@ 如上的设置,会在60s内、如果有1000个key发生改变就进行持久化。
#@ 可设置多个save选项,默认持久化到dump.rdb。
- Redis会将每个接收到的“写命令”通过write函数追加到appendonly.aof文件,重启Redis时通过该文件重建整个数据库。
- 由于os内核会缓存write函数所做的“修改”,可以使用fsync函数指定写入到磁盘的方式。
appendonly yes #启动aof持久化方式
appendfsync always #对每条“写命令”立即写至磁盘
appendfsync everysec #默认:每秒写入一次,在性能和可靠性之间的平衡
appendfsync no #依赖于os,不指定写入时机
### @快照方式:性能较好,但是快照间隔期间,如果宕机将造成数据丢失。
### @AOF模式:影响性能,不容易造成数据丢失。
### @如果Redis宕机:重启Redis即可,会自动使用redis.rdb、appendonly.aof恢复数据库。
- 关闭快照功能。
- 同时设置主从服务器都为AOF模式。
- 说明:如果仅对Slave进行持久化设置,重启时,Slave自动和Master进行同步,全部数据丢失
使用Jedis提供的Java API对Redis进行操作,是Redis官方推崇的方式;并且Jedis提供的对Redis的支持也是最为灵活、全面;不足之处,就是编码复杂度较高。
- 方式1:下载Jedis的依赖包jedis-2.1.0.jar,然后将其添加到classpath下面
- 方式2:使用Maven添加依赖,如下
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
Jedis jedis = new Jedis("192.168.142.12");
jedis.set("country","China");
String country = jedis.get("country");
jedis.del("country");
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.2</version>
</dependency>
redis.host=192.168.142.12 #Redis服务器地址
redis.port=6379 #服务端口
redis.timeout=3000 #超时时间:单位ms
redis.password=WangJie #授权密码
redis.pool.maxActive=200 #最大连接数:能够同时建立的“最大链接个数”
redis.pool.maxIdle=20 #最大空闲数:空闲链接数大于maxIdle时,将进行回收
redis.pool.minIdle=5 #最小空闲数:低于minIdle时,将创建新的链接
redis.pool.maxWait=3000 #最大等待时间:单位ms
redis.pool.testOnBorrow=true #使用连接时,检测连接是否成功
redis.pool.testOnReturn=true #返回连接时,检测连接是否成功
ResourceBundle bundle=ResourceBundle.getBundle("redis");
JedisPoolConfig config = new JedisPoolConfig();
String host = bundle.getString("redis.host");
...
config.setMaxActive(Integer.valueOf(bundle.getString("redis.pool.maxActive")));
...
config.setTestOnBorrow(Boolean.valueOf(bundle.getString("redis.pool.testOnBorrow")));
...
JedisPool pool = new JedisPool(config, host, port, timeout, password);
Jedis jedis = pool.getResource();
jedis.set("province", "shannxi");
String province = jedis.get("province");
jedis.del("province");
pool.returnResource(jedis);
redis是一个著名的key-value存储系统,而作为其官方推荐的Java客户端Jedis页非常强大和稳定,支持事物、管道及有Jedis自身实现的分布式。
jedis.rpush("userList","value");
jedis.rpush("userList","value1","value2");
jedis.rpop("userList");
jedis.lpush("userList","value");
jedis.lpush("userList","value1","value2");
jedis.lpop("userList");
List<String> userList=jedis.lrange("userList",0,-1);
jedis.del("userList");
jedis.lset("userList",1,"Nick Xu");
Long size=jedis.llen("userList");
jedis.ltrim("userList",1,2); //第二个参数为开始索引,第三个参数为结束索引
jedis.sadd("fruit","apple");
jedis.sadd("fruit","pear","watermelon");
Set<String> fruit=jedis.smembers("fruit");
jedis.srem("fruit","pear");
Long size=jedis.scard("fruit");
Boolean isMember=jedis.sismember("fruit","pear");
jedis.sadd("food","bread","milk");
Set<String> fruitFood=jedis.sunion("fruit","food");
Set<String> fruit_food=jedis.sdiff("fruit","food"); //此表达式中使用的sdiff表示的是,第一个Set集合(fruit)中含有而在第二个Set集合(food)中不存在的元素。
//如果想获取两个Set集合中独有的元素时,就可以两次使用sdiff。在对生成的两个集合求并即可。
jedis.zadd("user",22,"James");
jedis.zadd("user",24,"James"); //此时James的权重为24
Set<String> user=jedis.zrange("user",0,-1); //表示全部元素,当不知道集合中元素的多少的时候,可以使用-1来表示最后一位。
Map<String,String> capital=new HashMap<String,String>();
capital.put("shanXi",xiAn);
capital.put("shanDong","jiNan");
capital.put("beiJing","beiJing");
capital.put("heBei","shiJiaZhuang");
jedis.hmset("capitail",capital);
List<String> cities = jedis.hmget("capital", "shannxi", "shanghai");
Set<String> keys=jedis.keys("*");
Set<String> keys=jedis.keys(user.userid.*);
jedis.del("city");
Boolean isExists=jedis.exists("user.userid.14101");
jedis.setex("user.userid.14101",5,"James");
//上面等价于
//jedis.set("user.userid.14101","James");
//jedis.expire("user.userid.14101", 5);
Long seconds=jedis.ttl("user.userid.14101");
jedis.persist("user.userid.14101");
jedis.setex("Key",10,"Value");
jedis.set("Key","Value1"); //此时Key就不在具有失效时间。
jedis.set("amount",100+"");
jedis.incr("amount"); //每次增加1
jedis.decr("amount"); //每次减少1
jedis.incrBy("amount",20); //增加20
jedis.decrBy("amount",10); //减少10
jedis.flushDB();
jedis.flushAll();
Transaction tx=jedis.multi();
for(int i=0;i<10;i++){
tx.set("key"+i,"value"+i);
System.out.println("------------key"+i);
Thread.sleep(1000);
}
List<Object> results=tx.exec();
原来是redis默认只能localhost登录,所以需要开启远程登录。解决方法如下:
在Redis的配置文件中redis.windows.conf中,找到bind lcoalhost注释掉。
注释掉本机,局域网内的所有的计算机都能访问。
bind localhost只能本机访问,局域网内计算机都不等访问
bind 局域网IP 只能局域网内IP的机器访问,本地localhost都无法访问。
2、一定要配置防火墙 开放端口6379
3、redis配置认证密码 可在redis.windows.conf中来配置 requirepass即可,去掉行前的注释,并修改密码为所需的密码,保存文件
- 设置maxmemory maxmemory是为了限定Redis最大内存使用量。有多种方法设定他的大小。其中一种方法是通过CONFIG SET设定,如下:
127.0.0.1:6379> CONFIG get maxmemory
1) "maxmemory"
2) "0"
127.0.0.1:6379> CONFIG get maxmemory-policy
1) "maxmemory-policy"
2) "noeviction"
另一种方法是修改配置文件redis.conf
maxmemory 100mb
注意,在64bit系统下,maxmemory设置为0表示不限追Redis内存使用,在32bit系统下,maxmemory隐式不能超过3GB 当Redis内存使用达到指定的限制时,就需要选择一个置换的策略。
- 置换策略 当Redis内存使用达到maxmemory时,需要选择设置好的maxmemory-policy进行对老数据的置换 下面是可以选择的置换策略:
noeviction:不进行置换,表示即使内存达到上限也不进行置换,所有能引起内存增加的命令都会返回error
allkeys-lru:优先删除掉最近最不经常使用的key,用以保存新数据
volatile-lru:只从设置失效(expire set)的key中选择最近最不经常使用的key进行删除,用以保存新数据
allkeys-random:随机从all-keys中选择一些key进行删除,用以保存新数据
volatile-random:只从设置失效(expire set)的key中,选择一些key进行删除,用以保存新数据
volatile-ttl:只从设置失效(expire set)的key中,选出存活时间(TTL)最短的key进行删除,用以保存新数据
设置maxmemory-policy的方法和设置maxmemory方法类似,通过redis.conf或者通过CONFIG SET动态修改。
如果没有匹配到可以删除的key,那么volatile-lru、volatile-random和volatile-ttl策略和noeviction替换策略一样,不对任何key进行替换。
选择合适的置换策略是很重要的,这主要取决于你的应用的访问模式,当然你也以动态的修改置换策略,并通过用Redis命令, INFO去输出cache的命中率情况,进而可以对置换策略进行调优。
一般来说,有这样一些常用的经验:
在所有的key都是最近最经常使用,那么就需要选择allkeys-lru进行置换最近最不经常使用的key,如果你不确定使用
哪种策略,那么推荐使用allkeys-lru
如果所有的key的访问概率都是差不多的,那么可以选用allkeys-random策略去置换数据
如果对数据有足够的了解,能够为可以指定hint(通过expire/ttl指定),那么可以选择volatile-ttl进行置换
volatile-lru和volatile-random经常在一个Redis实例既做cache又做持久化的情况下用到,然而,最好的选择是使用两个Redis实例来解决这个问题。
设置是失效时间expire会占用一些内存,而采用allkeys-lru就没有必要设置失效时间,进而更有效的利用内存。
//学习地址 http://hello-nick-xu.iteye.com/blog/2075670 http://hello-nick-xu.iteye.com/blog/2077243?utm_source=tuicool&utm_medium=referral
CAP理论 C:一致性 A:可用性 P:分区可用性