出家如初,成佛有余

高扩展Web应用HTTP Session共享方案

Posted in Uncategorized by chuanliang on 2010/03/27

    在构建能够灵活地进行水平扩展、高可用性的Java Web应用程序时候,对http session的处理策略很大程度决定了应用程序的扩展性、可用性。一般而言对http session有如下的处理方案:

1、在服务器端不保存Session,完全无状态

     对于不需要保持用户状态的Web应用,采用Stateless是最为恰当的,因此就不存在Session共享的问题。REST (Representational State Transfer) 算是最为典型的例子。

2、基于浏览器Cookie的Session共享

      此种方案把用户相关的Session信息存储到浏览器的Cookie中,也称为客户端Session。

      采用Flash Cookie、URL重写的方式传递Session信息的方案也可以归为此类。

      缺点:只能够存储字符串、数值等基本类型的数据;Cookie大小存在限制;安全性;带宽及数据解压缩、网络传输性能问题。

3、基于数据库的Session共享,实现分布式应用间Session共享

     此种方案把Session信息存储到数据库表,这样实现不同应用服务器间Session信息的共享。诸如Websphere Portal、Weblogic Portal都采用了类似的方案。

     Tomcat Persistent Manager 的JDBC Based Store 提供了类似实现机制,表结构如下:

        create table tomcat_sessions (
            session_id     varchar(100) not null primary key,
            valid_session  char(1) not null,
            max_inactive   int not null,
            last_access    bigint not null,
            app_name       varchar(255),
            session_data   mediumblob,
            KEY kapp_name(app_name)
          );

        优点:实现简单

        缺点:由于数据库服务器相对于应用服务器更难扩展且资源更为宝贵,在高并发的Web应用中,最大的性能瓶颈通常在于数据库服务器。因此如果将Session存储到数据库表,频繁的增加、删除、查询操作很容易造成数据库表争用及加锁,最终影响业务。

 

4、基于应用服务器/Servlet容器的Clustering机制

        一些常用的应用服务器及Servlet容器的Clustering机制可以实现Session Replication的功能,例如Tomcat Clustering/Session ReplicationJboss buddy replication

         缺点:基于Clustering的Session复制性能很差,扩展性也很不行。

5、基于NFS的Session共享

         通过NFS方式来实现各台服务器间的Session共享,各台服务器只需要mount共享服务器的存储Session的磁盘即可,实现较为简单。但NFS对高并发读写的性能并不高,在硬盘I/O性能和网络带宽上存在较大瓶颈,尤其是对于Session这样的小文件的频繁读写操作。

        基于磁盘阵列/SAN/NAS等共享存储的方案道理也类似。

6、基于Terracotta、Ehcache、JBossCache等Java Caching方案实现Session共享

    如果系统架构是Java体系,可以考虑采用Terracotta、Ehcache、JbossCache、Oscache等Java Caching方案来实现Session 共享。

    缺点:架构用于非java体系很不方便;对于是诸如静态页面之类的缓存,采用Memcached的方案比Java更为高效

7、基于Memcached/Tokyo Tyrant 等Key-Value DB的Session共享

    整体说来此种方案扩展性最好,推荐使用。

    原理:Tomcat 服务器提供了org.apache.catalina.session.StandardManager 和org.apache.catalina.session.PersistentManager用于Session对象的管理,可以自定义PersistentManager的

Store 类来实现自己Memcached、Tokyo Tyrant、Redis等Key-Value DB的客户端。

    以Memcached的客户端为例(摘自Use MemCacheStore in Tomcat):

package com.yeeach;
import com.danga.MemCached.MemCachedClient; 
import com.danga.MemCached.SockIOPool;

public class MemCacheStore extends StoreBase implements Store {

	/**
	 * The descriptive information about this implementation.
	 */
	protected static String info = "MemCacheStore/1.0";

	/**
	 * The thread safe and thread local memcacheclient instance.
	 */
	private static final ThreadLocal<MemCachedClient> memclient = new ThreadLocal<MemCachedClient>();

	/**
	 * The server list for memcache connections.
	 */
	private List<String> servers = new ArrayList<String>();

	/**
	 * all keys for current request session.
	 */
	private List<String> keys = Collections
			.synchronizedList(new ArrayList<String>());

	/**
	 * Return the info for this Store.
	 */
	public String getInfo() {
		return (info);
	}

	/**
	 * Clear all sessions from the cache.
	 */
	public void clear() throws IOException {
		getMemcacheClient().flushAll();
		keys.clear();
	}

	/**
	 * Return local keyList size.
	 */
	public int getSize() throws IOException {
		return getKeyList().size();
	}

	/**
	 * Return all keys
	 */
	public String[] keys() throws IOException {
		return getKeyList().toArray(new String[] {});
	}

	/**
	 * Load the Session from the cache with given sessionId.
	 *
	 */
	public Session load(String sessionId) throws ClassNotFoundException,
			IOException {

		try {

			byte[] bytes = (byte[]) getMemcacheClient().get(sessionId);
			if (bytes == null)
				return null;
			ObjectInputStream ois = bytesToObjectStream(bytes);

			StandardSession session = (StandardSession) manager
					.createEmptySession();
			session.setManager(manager);
			session.readObjectData(ois);
			if (session.isValid() && !keys.contains(sessionId)) {
				keys.add(sessionId);
			}
			return session;

		} catch (Exception e) {
			return (null);
		}
	}

	/**
	 * transform a vaild Session from objectinputstream.
	 * Check which classLoader is responsible for the current instance.
	 *
	 * @param bytes
	 * @return ObjectInputStream with the Session object.
	 * @throws IOException
	 */
	private ObjectInputStream bytesToObjectStream(byte[] bytes)
			throws IOException {
		ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
		ObjectInputStream ois = null;
		Loader loader = null;
		ClassLoader classLoader = null;
		Container container = manager.getContainer();
		if (container != null)
			loader = container.getLoader();
		if (loader != null)
			classLoader = loader.getClassLoader();
		if (classLoader != null)
			ois = new CustomObjectInputStream(bais, classLoader);
		else
			ois = new ObjectInputStream(bais);
		return ois;
	}

	/**
	 * remove the session with given sessionId
	 */
	public void remove(String sessionId) throws IOException {
		getMemcacheClient().delete(sessionId);
		List<String> keyList = getKeyList();
		keyList.remove(sessionId);
	}

	/**
	 * Store a objectstream from the session into the cache.
	 */
	public void save(Session session) throws IOException {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		ObjectOutputStream oos = new ObjectOutputStream(baos);
		StandardSession standard = (StandardSession) session;
		standard.writeObjectData(oos);
		getMemcacheClient().add(session.getId(), baos.toByteArray());
		Object ob = getMemcacheClient().get(session.getId());
		List<String> keyList = getKeyList();
		keyList.add(session.getId());
	}

	/**
	 *
	 * @return
	 */
	private List<String> getKeyList() {
		return keys;
	}

	/**
	 * Simple instanc of the Memcache client and SockIOPool.
	 * @return memchacheclient
	 */
	private MemCachedClient getMemcacheClient() {
		if (memclient == null) {

			Integer[] weights = { 1 };
			// grab an instance of our connection pool
			SockIOPool pool = SockIOPool.getInstance();
			if (!pool.isInitialized()) {
				String[] serverlist = servers.toArray(new String[] {});
				// set the servers and the weights
				pool.setServers(serverlist);
				pool.setWeights(weights);

				// set some basic pool settings
				// 5 initial, 5 min, and 250 max conns
				// and set the max idle time for a conn
				// to 6 hours
				pool.setInitConn(5);
				pool.setMinConn(5);
				pool.setMaxConn(250);
				pool.setMaxIdle(1000 * 60 * 60 * 6);

				// set the sleep for the maint thread
				// it will wake up every x seconds and
				// maintain the pool size
				pool.setMaintSleep(30);

				// set some TCP settings
				// disable nagle
				// set the read timeout to 3 secs
				// and don't set a connect timeout
				pool.setNagle(false);
				pool.setSocketTO(3000);
				pool.setSocketConnectTO(0);

				// initialize the connection pool
				pool.initialize();
			}

			// lets set some compression on for the client
			// compress anything larger than 64k

			memclient.get().setCompressEnable(true);
			memclient.get().setCompressThreshold(64 * 1024);
		}
		return memclient.get();
	}

	public List<String> getServers() {
		return servers;
	}

	public void setServers(String serverList) {
		StringTokenizer st = new StringTokenizer(serverList, ", ");
		servers.clear();
		while (st.hasMoreTokens()) {
			servers.add(st.nextToken());
		}
	}

}
Tomcat 的配置文件:
<Context path="/test" docBase="test.war">
	<Manager className="org.apache.catalina.session.PersistentManager"
		distributable="true">
		<Store className="com.yeeach.MemcachedStore"
			servers="192.168.0.111:11211,192.168.0.112:11211" />
	</Manager>

</Context>

 

    这里只是作为测试演示了在Tomcat中集成Memcached的实现方案。并没有考虑性能、高可用、Memcached 存储Session的持久化(可以使用Memcachedb实现)、Session管理等问题。

    针对Tomcat与Memcached集成有一个开源项目memcached-session-manager  功能实现相对完善,尤其是其设计思想值得借鉴。

    The memcached session manager installed in a tomcat holds all sessions locally in the own jvm, just like the StandardManager does it as well.

    Additionally, after a request was finished, the session (only if existing) is additionally sent to a memcached node for backup.

    When the next request for this session has to be served, the session is locally available and can be used, after this second request is finished the session is updated in the memcached node.

 

    对于采用Tokyo Tyrant、Redis等当下流行的Key-Value DB实现机制类似。       

 

 

参考资料:

   Session, state and scalability

   Why memcached is probably a bad idea for your Java app

 

Advertisements

运营型互联网企业“产品平台”思考

Posted in Uncategorized by chuanliang on 2010/03/20

    对于运营型的互联网企业而言,产品的研发及运营能力是企业最为核心的竞争力。如果所有的产品能够通过一些基础产品的组合、复用、简单个性化就可以搭建出另外一个产品,那产品研发成本、运营成本将极大程度地降低。因此“产品平台”的概念成为所有企业的梦想之一,正如“组件化”之于软件开发一样。这里我们可以将“产品平台”粗略定义为:以平台化、系统化方式来管理产品,保证产品间公用元素最大程度的复用。   

1、为什么需要“产品平台”?

总结一下常见的产品研发常见问题,由此可以看出平台化的重要性。

1.1 产品问题

  • 产品规划不具有前瞻性、整体性,不断推倒再来
  • 缺乏有效的需求积累机制
  • 不断变化的需求,产品生命周期相对短暂,很难产品化
  • 产品线产品间没有复用,同样的功能重复开发

1.2 研发问题

  • 系统属于不同研发团队开发维护,系统异常庞大、复杂,没有人能够完全明白
  • 用户界面异常复杂、凌乱,易用性很差
  • 开发周期很短,短迭代、快速上线,文档很少、质量没有保证
  • 缺乏公用组件,缺乏知识积累和共享机制
  • 技术研发与产品研发没有分离,缺乏技术研发体系

1.3 运营问题

  • 没有统一运营平台,每个系统都有自己一套运营系统
  • 有统一的运营管理系统,但缺少统一规划,运营系统异常复杂,开通一个用户需要经过10多步
  • 运营以处理客户投诉为主,没有做到客户运营

1.4 管理问题

  • 缺乏有效的考核和激励机制
  • 缺乏有效的培养机制,研发人员职业素质不足
  • 不同产品线及职能部门间跨部门协作很难

2、产品平台

  “产品平台”不单纯只是产品术语或是技术术语,要达成“产品平台”目标,必须在运营型互联网企业的市场、营销、产品、技术研发、运营、管理等多个环节以平台化思路来建设,包括:

  • 市场营销平台化
  • 产品平台化
  • 技术平台化
  • 运营平台化
  • 管理体系化

 

产品管理,产品平台,平台化,product platform

 

 

Cognos 8.3用户权限控制入门

Posted in Uncategorized by chuanliang on 2010/03/14

    学习Cognos 8.3入门中,需要实现Cognos与现有业务系统集成,尤其是用户权限部分。官方文档及网上的教程对Cognos用户权限控制的实现机制都语焉不详,迫切需要一个快餐式的Step-By-Step的学习文档。整理一下学习的东西,希望对新手们有所帮助。

    目的:

    1. 采用OpenDS存储组织机构及用户信息,实现OpenDS与Cognos集成

    2. 使用Cognos Framework Manager来实现用户数据过滤控制,实现同一报表用户只能够看见自己的数据

    3. 二次开发实现cognos与业务系统的用户数据集成

  下载《Cognos 8.3用户权限控制入门》

 

Technorati 标签: ,,,,

电子商务平台之“推荐作为服务”

Posted in Uncategorized by chuanliang on 2010/03/07

    在亚马逊这样的电子商务标杆企业的示范下,推荐系统对于电子商务网站的价值已被大家所认同,例如:增加网站的访问量,提升销售额;提高网站的交叉销售能力;增加顾客在网店上的停留时间,浏览更多的商品;将网站的浏览者转变为购买者等等。因此大家都希望能够拥有自己的推荐系统。

    但相对于网站开发技术而言,推荐系统由于涉及数据仓库、数据挖掘、统计分析、人工智能等相关技术,因此技术门槛要高得多,对于研发能力相对较弱的中小型的企业而言,要自己研发推荐系统难度很大。于是乎诞生了一些以“推荐作为服务”(Recommendation as a Service)的公司。

1、推荐服务的基本模式

    这些公司拥有推荐系统核心技术,通过SaaS模式对外提供推荐服务,一般的服务方式如下:

    1)、以接口、批量上传等形式导入合作伙伴的产品目录

    2)、在合作伙伴网站页面嵌入用于跟踪用户行为的javascript脚本

    3)、通过对诸如商品信息、历史用户数据、用户行为(包括搜索、网站点击行为、购买历史、喜好、购物车、收藏历史)等行为数据的汇总分析,建立网站相应的推荐模型

    4)、用户登录网站时候,根据用户历史行为数据实时分析预测用户的喜好,产生个性化推荐。

    下图摘自StrandsMybuys 公司的业务流程图,基本上概括了推荐服务的核心模型

recommendation engine,推荐引擎,推荐系统,协同过滤,开放平台,推荐作为服务,recommendation as a service

                                                 Strands的模型

 

recommendation engine,推荐引擎,推荐系统,协同过滤,开放平台,推荐作为服务,recommendation as a service

                                                    Mybuys 的模型

    尽管推荐服务核心算法的理论基础基本上类似,但不同行业推荐对象对应的模型不尽相同(例如电子商务、SNS社区、媒体站点),更为重要的是由于各公司商业模式的不同,不同的公司对于推荐服务有不同的要求,因此推荐服务提供商针对不同行业及不同公司所采用推荐算法及模型实现都会有所不同。   

2、推荐服务提供商

   2.1、国外的“推荐作为服务”提供商:

    StrandsMybuysBaynoteLoomiaAggregrate KnowledgeRichRelevanceOutBrainATGAvail IntelligenceCertona、    ChoicestreamApture

recommendation engine,推荐引擎,推荐系统,协同过滤,开放平台,推荐作为服务,recommendation as a service 

 

2.2、国内的“推荐作为服务”提供商:

    百分点麦路

    麦路最初以“推荐作为服务”作为商业模式,目前重点已经转向运营购物返现联盟发现宝

    而百分点仍然专注在“推荐作为服务”上,相对于麦路更加专业,百分点推荐技术研究中心及电子期刊收集了一些有价值的资料。尽管作为纯技术驱动的公司在国内现实的商业环境下生存相对较难,但随着国内电子商务的繁荣及成熟,相信像百分点这样专业化的公司会有美好的前景。

3、几点思考:

3.1、“推荐作为服务”的商业模式

    1)、独立的推荐服务提供商

    2)、依托于某个电子商务开放平台(例如淘宝开放平台)、SNS开放平台提供推荐服务

    3)、依托于广告联盟

    4)、依托于网络营销、购物返现联盟

    5)、依托于行业垂直搜索引擎公司

    电子商务、SNS社区等互联网新兴应用的高速发展,对个性化推荐的需求越来越强烈,因此那些专注于“推荐作为服务”这一领域的推荐服务提供商会有较大的成长空间,尽管尚有很长的路要走。

   “推荐作为服务”的一种趋势是多种模式的结合,尤其是与开放平台、网络营销联盟、搜索引擎多种模式的结合,因此“推荐作为服务”提供商最终可能变成网路营销服务提供商、垂直搜索引擎公司、广告媒体公司等等。

3.2、、“推荐作为服务”的核心价值

    “推荐作为服务”提供商拥有的最为核心财富不是推荐技术本身,而是通过推荐服务所积累的海量数据,特别是用户数据和项目(item)数据。这正如Google自身最核心的财富不是搜索引擎本身,而是对于用户点击流数据。因此从这点来说,“推荐作为服务”最大的实践者其实是Google。

    用户数据:当下的“推荐作为服务”提供商基本上都围绕一个应用或一个平台来提供服务,并没有以用户网络身份标识为中心来整合各种用户行为数据。如果能够借助opensocial、openid、oauth等开放协议整合用户的网络身份,获得用户各种网络活动的数据,为用户提供更加个性、精准、实时的推荐服务,这样的推荐服务对用户极大的使用价值。

    项目数据:所谓的项目(item)数据的内涵可以是电子商务平台的商品,可以是社会化媒体的一个视频、一篇blog,可以是搜索引擎的搜索关键词,而这些恰恰是那些传统的电子商务、搜索引擎、广告巨头们的关注点。但这并不意味着“推荐作为服务”提供商无法与这些巨头们竞争。“推荐作为服务”之所以能够蓬勃发展,正说明了目前的巨头们所提供的服务在这些领域并不能很好满足用户的需求。例如在实时网络(Real-Time)、开放平台等领域。

    对于用户而言,推荐服务最核心的价值在于更加个性化、精准、实时的推荐,因此推荐服务未来的趋势之一是对用户身份及数据的整合。

    对于众多的中小企业而言,推荐服务最核心的价值在于能够帮助其带来流量、促成交易、创造交易,因此推荐服务未来的趋势之一应该是与网络营销、广告联盟等服务更加的紧密结合。

3.3、“推荐作为服务”的最佳实践

    Strands 的Francisco Martin 在RecSys 2009上的演讲 RecSys 2009 Keynote: Top 10 Lessons Learned Developing, Deploying, and Operating Real-World Recommender Systems 分享了Strands在此方面的经验,很精彩:

  • Lesson 1. Make sure a recommender is really needed! Do you have lots of recommendable items? Many diverse customers?… also think Return-on-Invesment… a more sophisticated recommender may not deliver a better ROI.
  • Lesson 2. Make sure the recommendations make strategic sense. Is the best recommendation for the customer also the best for the business? What is the difference between a good and useful recommendation? Good recommendations vs useful recs; obvious recommendations may not be useful; risky recs may deliver better long-term value.
  • Lesson 3. Choose the right partner! Select the right rec vendor vs hire some #recsys09 students. If you are a big company the best thing you can do is organize a contest.
  • Lesson 4. Forget about cold-start problems (!) …. just be creative. The internet has all the data that you need (somewhere…).
  • Lesson 5. Get the right balance between data and algorithms. 70% of the success of a recommendation system is in the data, the other 30% in the algorithm.
  • Lesson 6. Finding correlated items is easy but deciding what, how, and when to present them to the user is hard… or don’t just recommend for the sake of it. Remember, user attention is a scarce and valuable resource. Use it wisely! … dont make a recommendations to a customer who is just about to pay for items at the checkout! User interface should get at least 50% of your attention.
  • Lesson 7 Don’t waste time computing nearest neighbours (use social connections)… just mine the social graph. Might miss useful connections?
  • Lesson 8 Don’t wait to scale!
  • Lesson 9: Choose the right feedback mechanism. Stars vs thumbs …. the YouTube problem. More research on implicit and other feedback mechanisms is needed. The perfect rating system is no rating system! … focus on the interface.
  • Lesson 10 Measure Everything! … business control and analytics is a big opportunity here.

 

4、参考资料

  RecSys 2009 Keynote: Top 10 Lessons Learned Developing, Deploying, and Operating Real-World Recommender Systems

  5 Problems of Recommender Systems

  Readwriteweb series on recommendation technologies

  Baynote, Strands, RichRelevance — will they survive the “recommendation engine” consolidation?