关键字:redis for Windows

一、windows下安装redis


1:首先下载redis:redis-2.0.2.zip (32 bit),解压。
从下面地址下:http://code.google.com/p/servicestack/wiki/RedisWindowsDownload,看到下面有redis-2.0.2.zip (32 bit),就是他了,下载完成后,解压到D:\redis-2.0.2.
2:创建redis.conf文件:
这是一个配置文件,指定了redis的监听端口,timeout等。如下面有:port 6379。
把下面内容COPY到一新建文件中,取名redis.conf,再保存到redis-2.0.2目录下:


# Redis configuration file example 


# By default Redis does not run as a daemon. Use 'yes' if you need it. 

# Note that Redis will write a pid file in /var/run/redis.pid when daemonized. 

daemonize no 


# When run as a daemon, Redis write a pid file in /var/run/redis.pid by default. 

# You can specify a custom pid file location here. 

pidfile /var/run/redis.pid 


# Accept connections on the specified port, default is 6379 

port 6379 


# If you want you can bind a single interface, if the bind option is not 

# specified all the interfaces will listen for connections. 

# 

# bind 127.0.0.1 


# Close the connection after a client is idle for N seconds (0 to disable) 

timeout 300 


# Set server verbosity to 'debug' 

# it can be one of: 

# debug (a lot of information, useful for development/testing) 

# notice (moderately verbose, what you want in production probably) 

# warning (only very important / critical messages are logged) 

loglevel debug 


# Specify the log file name. Also 'stdout' can be used to force 

# the demon to log on the standard output. Note that if you use standard 

# output for logging but daemonize, logs will be sent to /dev/null 

logfile stdout 


# Set the number of databases. The default database is DB 0, you can select 

# a different one on a per-connection basis using SELECT <dbid> where 

# dbid is a number between 0 and 'databases'-1 

[color=red]databases 16[/color] 


################################ SNAPSHOTTING ################################# 

# 

# Save the DB on disk: 

# 

# save <seconds> <changes> 

# 

# Will save the DB if both the given number of seconds and the given 

# number of write operations against the DB occurred. 

# 

# In the example below the behaviour will be to save: 

# after 900 sec (15 min) if at least 1 key changed 

# after 300 sec (5 min) if at least 10 keys changed 

# after 60 sec if at least 10000 keys changed 

save 900 1 

save 300 10 

save 60 10000 


# Compress string objects using LZF when dump .rdb databases? 

# For default that's set to 'yes' as it's almost always a win. 

# If you want to save some CPU in the saving child set it to 'no' but 

# the dataset will likely be bigger if you have compressible values or keys. 

rdbcompression yes 


# The filename where to dump the DB 

dbfilename dump.rdb 


# For default save/load DB in/from the working directory 

# Note that you must specify a directory not a file name. 

dir ./ 


################################# REPLICATION ################################# 


# Master-Slave replication. Use slaveof to make a Redis instance a copy of 

# another Redis server. Note that the configuration is local to the slave 

# so for example it is possible to configure the slave to save the DB with a 

# different interval, or to listen to another port, and so on. 

# 

# slaveof <masterip> <masterport> 


# If the master is password protected (using the "requirepass" configuration 

# directive below) it is possible to tell the slave to authenticate before 

# starting the replication synchronization process, otherwise the master will 

# refuse the slave request. 

# 

# masterauth <master-password> 


################################## SECURITY ################################### 


# Require clients to issue AUTH <PASSWORD> before processing any other 

# commands. This might be useful in environments in which you do not trust 

# others with access to the host running redis-server. 

# 

# This should stay commented out for backward compatibility and because most 

# people do not need auth (e.g. they run their own servers). 

# 

# requirepass foobared 


################################### LIMITS #################################### 


# Set the max number of connected clients at the same time. By default there 

# is no limit, and it's up to the number of file descriptors the Redis process 

# is able to open. The special value '0' means no limts. 

# Once the limit is reached Redis will close all the new connections sending 

# an error 'max number of clients reached'. 

# 

# maxclients 128 


# Don't use more memory than the specified amount of bytes. 

# When the memory limit is reached Redis will try to remove keys with an 

# EXPIRE set. It will try to start freeing keys that are going to expire 

# in little time and preserve keys with a longer time to live. 

# Redis will also try to remove objects from free lists if possible. 

# 

# If all this fails, Redis will start to reply with errors to commands 

# that will use more memory, like SET, LPUSH, and so on, and will continue 

# to reply to most read-only commands like GET. 

# 

# WARNING: maxmemory can be a good idea mainly if you want to use Redis as a 

# 'state' server or cache, not as a real DB. When Redis is used as a real 

# database the memory usage will grow over the weeks, it will be obvious if 

# it is going to use too much memory in the long run, and you'll have the time 

# to upgrade. With maxmemory after the limit is reached you'll start to get 

# errors for write operations, and this may even lead to DB inconsistency. 

# 

# maxmemory <bytes> 


############################## APPEND ONLY MODE ############################### 


# By default Redis asynchronously dumps the dataset on disk. If you can live 

# with the idea that the latest records will be lost if something like a crash 

# happens this is the preferred way to run Redis. If instead you care a lot 

# about your data and don't want to that a single record can get lost you should 

# enable the append only mode: when this mode is enabled Redis will append 

# every write operation received in the file appendonly.log. This file will 

# be read on startup in order to rebuild the full dataset in memory. 

# 

# Note that you can have both the async dumps and the append only file if you 

# like (you have to comment the "save" statements above to disable the dumps). 

# Still if append only mode is enabled Redis will load the data from the 

# log file at startup ignoring the dump.rdb file. 

# 

# The name of the append only file is "appendonly.log" 

# 

# IMPORTANT: Check the BGREWRITEAOF to check how to rewrite the append 

# log file in background when it gets too big. 


appendonly no 


# The fsync() call tells the Operating System to actually write data on disk 

# instead to wait for more data in the output buffer. Some OS will really flush 

# data on disk, some other OS will just try to do it ASAP. 

# 

# Redis supports three different modes: 

# 

# no: don't fsync, just let the OS flush the data when it wants. Faster. 

# always: fsync after every write to the append only log . Slow, Safest. 

# everysec: fsync only if one second passed since the last fsync. Compromise. 

# 

# The default is "always" that's the safer of the options. It's up to you to 

# understand if you can relax this to "everysec" that will fsync every second 

# or to "no" that will let the operating system flush the output buffer when 

# it want, for better performances (but if you can live with the idea of 

# some data loss consider the default persistence mode that's snapshotting). 


appendfsync always 

# appendfsync everysec 

# appendfsync no 


############################### ADVANCED CONFIG ############################### 


# Glue small output buffers together in order to send small replies in a 

# single TCP packet. Uses a bit more CPU but most of the times it is a win 

# in terms of number of queries per second. Use 'yes' if unsure. 

glueoutputbuf yes 


# Use object sharing. Can save a lot of memory if you have many common 

# string in your dataset, but performs lookups against the shared objects 

# pool so it uses more CPU and can be a bit slower. Usually it's a good 

# idea. 

# 

# When object sharing is enabled (shareobjects yes) you can use 

# shareobjectspoolsize to control the size of the pool used in order to try 

# object sharing. A bigger pool size will lead to better sharing capabilities. 

# In general you want this value to be at least the double of the number of 

# very common strings you have in your dataset. 

# 

# WARNING: object sharing is experimental, don't enable this feature 

# in production before of Redis 1.0-stable. Still please try this feature in 

# your development environment so that we can test it better. 

# shareobjects no 

# shareobjectspoolsize 1024



3:在cmd下面执行以下命令,指定它使用我们的redis.conf,同时也是启动,把redis运行起来,这里指定用redis.conf的配置运行服务器
D:\redis-2.0.2>redis-server.exe redis.conf

4:开一新DOS窗口cmd.执行以下命令,这是Redis的客户端程序:
redis-cli.exe -h 172.18.5.1 -p 6379
172.18.5.1是我本机IP地址,端口6379就是上面配置文件中指定的监听端口
执行完成后,应该能看到redis启动了,这时在第一个cmd窗口可以看到连接信息。
执行一条保存key value操作
set mystock 300156
再查询一下
get mystock

=================================



二、redis配置选项:

指定redis的配置文件,如没有指定,则使用默认设置
D:\redis-2.0.0-rc2>redis-server.exe redis.conf

redis.conf配置选项如下
daemonize 是否以后台进程运行,默认为no
pidfile 如以后台进程运行,则需指定一个pid,默认为/var/run/redis.pid
bind 绑定主机IP,默认值为127.0.0.1(注释)
port 监听端口,默认为6379
timeout 超时时间,默认为300(秒)
loglevel 日志记录等级,有4个可选值,debug,verbose(默认值),notice,warning
logfile 日志记录方式,默认值为stdout
databases 可用数据库数,默认值为16,默认数据库为0
save <seconds> <changes> 指出在多长时间内,有多少次更新操作,就将数据同步到数据文件。这个可以多个条件配合,比如默认配置文件中的设置,就设置了三个条件。
save 900 1 900秒(15分钟)内至少有1个key被改变
save 300 10 300秒(5分钟)内至少有300个key被改变
save 60 10000 60秒内至少有10000个key被改变
rdbcompression 存储至本地数据库时是否压缩数据,默认为yes
dbfilename 本地数据库文件名,默认值为dump.rdb
dir 本地数据库存放路径,默认值为 ./
slaveof <masterip> <masterport> 当本机为从服务时,设置主服务的IP及端口(注释)
masterauth <master-password> 当本机为从服务时,设置主服务的连接密码(注释)
requirepass 连接密码(注释)
maxclients 最大客户端连接数,默认不限制(注释)
maxmemory <bytes> 设置最大内存,达到最大内存设置后,Redis会先尝试清除已到期或即将到期的Key,当此方法处理后,任到达最大内存设置,将无法再进行写入操作。(注释)
appendonly 是否在每次更新操作后进行日志记录,如果不开启,可能会在断电时导致一段时间内的数据丢失。因为redis本身同步数据文件是按上面save条件来同步的,所以有的数据会在一段时间内只存在于内存中。默认值为no
appendfilename 更新日志文件名,默认值为appendonly.aof(注释)
appendfsync 更新日志条件,共有3个可选值。no表示等操作系统进行数据缓存同步到磁盘,always表示每次更新操作后手动调用fsync()将数据写到磁盘,everysec表示每秒同步一次(默认值)。
vm-enabled 是否使用虚拟内存,默认值为no
vm-swap-file 虚拟内存文件路径,默认值为/tmp/redis.swap,不可多个Redis实例共享
vm-max-memory 将所有大于vm-max-memory的数据存入虚拟内存,无论vm-max-memory设置多小,所有索引数据都是内存存储的(Redis的索引数据就是keys),也就是说,当vm-max-memory设置为0的时候,其实是所有value都存在于磁盘。默认值为0。

Redis官方文档对VM的使用提出了一些建议:
当你的key很小而value很大时,使用VM的效果会比较好.因为这样节约的内存比较大.
当你的key不小时,可以考虑使用一些非常方法将很大的key变成很大的value,比如你可以考虑将key,value组合成一个新的value.
最好使用linux ext3 等对稀疏文件支持比较好的文件系统保存你的swap文件.
vm-max-threads这个参数,可以设置访问swap文件的线程数,设置最好不要超过机器的核数.如果设置为0,那么所有对swap文件的操作都是串行的.可能会造成比较长时间的延迟,但是对数据完整性有很好的保证.redis-cli.exe:命令行客户端,测试用
D:\redis-2.0.0-rc2>redis-cli.exe -h 127.0.0.1 -p 6379

三、redis java操作(包括list/Map/删除/新增/覆盖/排序等都支持)

import org.junit.After; 

 import org.junit.Before; 

 import org.junit.Test; 

 import redis.clients.jedis.Jedis; 

 import redis.clients.jedis.JedisPool; 

 import redis.clients.jedis.JedisPoolConfig; 


 import javax.sound.midi.Soundbank; 

 import java.util.*; 


 /** 

 * @author: flychao88 

 * Time: 2012.5.7 16:23:15 

 */ 

 public class RedisTest { 

 JedisPool pool; 

 Jedis jedis; 

 @Before 

 public void setUp() { 

 pool = new JedisPool(new JedisPoolConfig(), "172.16.100.184"); 


 jedis = pool.getResource(); 

 jedis.auth("password"); 

 } 


 /** 

 * Redis存储初级的字符串 

 * CRUD 

 */ 

 @Test 

 public void testBasicString(){ 

 //-----添加数据---------- 

 jedis.set("name","minxr");//向key-->name中放入了value-->minxr 

 System.out.println(jedis.get("name"));//执行结果:minxr 


 //-----修改数据----------- 

 //1、在原来基础上修改 

 jedis.append("name","jarorwar"); //很直观,类似map 将jarorwar append到已经有的value之后 

 System.out.println(jedis.get("name"));//执行结果:minxrjarorwar 


 //2、直接覆盖原来的数据 

 jedis.set("name","闵晓荣"); 

 System.out.println(jedis.get("name"));//执行结果:闵晓荣 


 //删除key对应的记录 

 jedis.del("name"); 

 System.out.println(jedis.get("name"));//执行结果:null 


 /** 

 * mset相当于 

 * jedis.set("name","minxr"); 

 * jedis.set("jarorwar","闵晓荣"); 

 */ 

 jedis.mset("name","minxr","jarorwar","闵晓荣"); 

 System.out.println(jedis.mget("name","jarorwar")); 


 } 


 /** 

 * jedis操作Map 

 */ 

 @Test 

 public void testMap(){ 

 Map<String,String> user=new HashMap<String,String>(); 

 user.put("name","minxr"); 

 user.put("pwd","password"); 

 jedis.hmset("user",user); 

 //取出user中的name,执行结果:[minxr]-->注意结果是一个泛型的List 

 //第一个参数是存入redis中map对象的key,后面跟的是放入map中的对象的key,后面的key可以跟多个,是可变参数 

 List<String> rsmap = jedis.hmget("user", "name"); 

 System.out.println(rsmap); 


 //删除map中的某个键值 

 // jedis.hdel("user","pwd"); 

 System.out.println(jedis.hmget("user", "pwd")); //因为删除了,所以返回的是null 

 System.out.println(jedis.hlen("user")); //返回key为user的键中存放的值的个数1 

 System.out.println(jedis.exists("user"));//是否存在key为user的记录 返回true 

 System.out.println(jedis.hkeys("user"));//返回map对象中的所有key [pwd, name] 

 System.out.println(jedis.hvals("user"));//返回map对象中的所有value [minxr, password] 


 Iterator<String> iter=jedis.hkeys("user").iterator(); 

 while (iter.hasNext()){ 

 String key = iter.next(); 

 System.out.println(key+":"+jedis.hmget("user",key)); 

 } 


 } 


 /** 

 * jedis操作List 

 */ 

 @Test 

 public void testList(){ 

 //开始前,先移除所有的内容 

 jedis.del("java framework"); 

 System.out.println(jedis.lrange("java framework",0,-1)); 

 //先向key java framework中存放三条数据 

 jedis.lpush("java framework","spring"); 

 jedis.lpush("java framework","struts"); 

 jedis.lpush("java framework","hibernate"); 

 //再取出所有数据jedis.lrange是按范围取出, 

 // 第一个是key,第二个是起始位置,第三个是结束位置,jedis.llen获取长度 -1表示取得所有 

 System.out.println(jedis.lrange("java framework",0,-1)); 

 } 


 /** 

 * jedis操作Set 

 */ 

 @Test 

 public void testSet(){ 

 //添加 

 jedis.sadd("sname","minxr"); 

 jedis.sadd("sname","jarorwar"); 

 jedis.sadd("sname","闵晓荣"); 

 jedis.sadd("sanme","noname"); 

 //移除noname 

 jedis.srem("sname","noname"); 

 System.out.println(jedis.smembers("sname"));//获取所有加入的value 

 System.out.println(jedis.sismember("sname", "minxr"));//判断 minxr 是否是sname集合的元素 

 System.out.println(jedis.srandmember("sname")); 

 System.out.println(jedis.scard("sname"));//返回集合的元素个数 

 } 


 @Test 

 public void test() throws InterruptedException { 

 //keys中传入的可以用通配符 

 System.out.println(jedis.keys("*")); //返回当前库中所有的key [sose, sanme, name, jarorwar, foo, sname, java framework, user, braand] 

 System.out.println(jedis.keys("*name"));//返回的sname [sname, name] 

 System.out.println(jedis.del("sanmdde"));//删除key为sanmdde的对象 删除成功返回1 删除失败(或者不存在)返回 0 

 System.out.println(jedis.ttl("sname"));//返回给定key的有效时间,如果是-1则表示永远有效 

 jedis.setex("timekey", 10, "min");//通过此方法,可以指定key的存活(有效时间) 时间为秒 

 Thread.sleep(5000);//睡眠5秒后,剩余时间将为<=5 

 System.out.println(jedis.ttl("timekey")); //输出结果为5 

 jedis.setex("timekey", 1, "min"); //设为1后,下面再看剩余时间就是1了 

 System.out.println(jedis.ttl("timekey")); //输出结果为1 

 System.out.println(jedis.exists("key"));//检查key是否存在 

 System.out.println(jedis.rename("timekey","time")); 

 System.out.println(jedis.get("timekey"));//因为移除,返回为null 

 System.out.println(jedis.get("time")); //因为将timekey 重命名为time 所以可以取得值 min 


 //jedis 排序 

 //注意,此处的rpush和lpush是List的操作。是一个双向链表(但从表现来看的) 

 jedis.del("a");//先清除数据,再加入数据进行测试 

 jedis.rpush("a", "1"); 

 jedis.lpush("a","6"); 

 jedis.lpush("a","3"); 

 jedis.lpush("a","9"); 

 System.out.println(jedis.lrange("a",0,-1));// [9, 3, 6, 1] 

 System.out.println(jedis.sort("a")); //[1, 3, 6, 9] //输入排序后结果 

 System.out.println(jedis.lrange("a",0,-1)); 


 }




六、redis和memcached比较

1、memcached多线程 redis单线程

2、memcached支持简单的key/value redis支持最为常用的数据类型主要由五种:String、Hash、List、Set和Sorted Set(最吸引人的就此,而且可以对list排序等)

3、memcached客户端实现分布式 redis服务器端实现分布式

4、