ASP页面级缓存

很早以前的一个想法及实现方式,因为当时有过一套系统是使用ASP实现,中间也有过性能优化。在考虑到成本时,只对部分页面进行缓存处理,从而提升性能。

在ASP.NET下面,很容易利用一些static方式来做页面级别缓存效果非常好,而模拟static实现方式是最直接方案。而在ASP平台下除了Application、Session对象是把数据存储在内存当中,以下我分析两种方式的利弊。

Session对象

Session自身是以用户级会话方式,所以把其作为缓存很明显只是对当前用户有效,而页面部分数据其实是所有人都共同拥有的,光这一点很难把Session对象当做页面级缓存存储对象。

并大概会遇到以下几种麻烦点:

  1. 用户级会员,仅对当前用户有效。
  2. 当工作在多进程存在时,命中率是一个问题。
  3. 有效期。
  4. 不存在锁问题。

Application对象

以Session相比较Application是应用级存储空间,换言之,只要存在任何页面都可以调用到,并且不存在工作在多进程无法共享问题。

而接下来我们得考虑数据更新问题,因为这类数据并非一层不变,页面级数据更新大概有两种方式:

  • 程序调度
  • 用户触发

程序调度来对于ASP.NET来说容易得多,利用timer很轻松解决问题。而ASP平台下相对于简单得多只有用户触发和时间点两者结合。

比如我们每10分钟调用一次,缓存数据时记录当前时间,并且当每一次读取数据时对其进行判断是否过期。

因此在这几个问题下面,我封装一个类,大致代码如下:

Class Cls_Cache
    ' 增加
    Public Sub Add(ByVal key, ByVal val, ByVal expire)
        Application.Lock
            Application(key & "_time") = DateAdd("n", expire, Now)
            Application(key) = val
        Application.UnLock
    End Sub

    ' 增加不过期缓存
    Public Sub AddNotExpire(ByVal key, ByVal val)
        Application.Lock
            Application(key) = val
        Application.UnLock
    End Sub

    ' 是否存在
    Public Function Exists(ByVal key)
        Exists = True
        If IsDate(Application(key & "_time")) Then
            ' 过期并做移除处理
            If CDate(Application(key & "_time")) < Now() Then
                Remove(key)
                Exists = False
                Exit Function
            End If
        End If
        Exists = True
    End Function

    ' 获取缓存数据
    Public Function Item(ByVal key)
        If Not Exists(key) Then
            Item = ""
        Else
            Item = Application(key)
        End If
    End Function

    ' 移除
    Public Sub Remove(ByVal key)
        Application.Lock
            Application.Contents.Remove(key & "_time")
            Application.Contents.Remove(key)
        Application.UnLock
    End Sub
End Class

以上并没有做异常处理,弱爆了。而在具体业务逻辑层时,需要做的获取数据,如果数据不存在而读取数据库并重新缓存。

例如:获取点击排行新闻,并且每10分钟自动更新一次。

Function GetHotNews()
    Dim cache, KEY, T
    KEY = "HotNews"
    T = 10
    Set cache = New Cls_Cache
    If Not cache.Exists(KEY) Then
        ' 逻辑处理
        cache.Add KEY, "点击排行新闻"&now(), T
    End If
    GetHotNews = cache.Item(KEY)
End Function

后续

相比较有点繁琐,特别是在代码维护方面,所以我给出个建议。

对于业务逻辑层建议模块化,不建议使用Class来封装大部分业务逻辑,本来目地是页面级缓存,在页面加载时Include到对应的目标文件当中。

以上希望那种还处于ASP时代的朋友有点帮助。

Enyim Memcached 客户端几点偶遇

二进制协议

MemcachedClientConfiguration.Protocol = Binary,这是新版默认配置,但是如果你的Memcached版本不是在1.3以上,将无法支持二进制协议传输模式,特别是Memcached for win32 好像还是处于1.2.4版本上,这里只能需要配置 MemcachedClientConfiguration.Protocol = Text

Get泛型

我是第一次使用这个版本的客户端,这里有个比较好的就是支持泛型的获取数据。基本实现方式:

return TryGet(key, out tmp) ? (T)tmp : default(T);

而Get

return this.TryGet(key, out tmp) ? tmp : null;

因此在本质上并没有太多的区别,减少类型转换,我建议使用as简单明了。

尽量只创建过少的MemcachedClient

Enyim.MemcachedClient支持不同池配置,我建议对每个Client做Singleton模式。

配置问题

其实我不想说这个事,但是我只是想提醒一下,Enyim.MemcachedClient在配置时,都是对套接字池的配置(即:Scoket Pool),对于入门来讲只要了解.NET中的套接字池配置就可以,哪怕不通过Web.Config,也可以通过很简单的 MemcachedClientConfiguration.SocketPool 套接字池配置,因些不要太过于复杂化。

Memcached for win32 命令描述

我的系统是WIN7,所以如果遇到什么Telnet无法使用的,是因为WIN7默认没有安装Telnet client。可能还有遇到权限问题,详见:windows7下安装Memcached

以下内容是转载的一篇文章,方便查阅:

Connecting to Memcached server with telnet

telnet <hostname> <port>

In the following \r\n mean you have to type enter in telnet console

If Memcached server send ERROR or CLIENT_ERROR, something is false with the command, if it’s SERVER_ERROR, server itself is in trouble

Retrieval Commands

Parameters :

<key> : the key of the data stored to retrieve

<key>* mean you can request value of multiple keys separated by whitespace

These commands return :

VALUE <flag> <bytes>\r\n<data> (see the following for explanation of <bytes> and <flag>)

END indicate the end of response

Get

Get value from key

Telnet command : get <key>*\r\n

get key
VALUE key 0 4
data
END

Gets

Get value from key along with a cas token (to use with cas command)

Telnet command : gets <key>*\r\n

get key
VALUE key 0 4
data
END

 

Storage Commands

Parameters :

<key> : the key of the data stored

<flags> : 32-bit unsigned integer that the server store with the data (provided by the user), and return along the data when the item is retrieved

<exptime> : expiration time in seconds, 0 mean no delay, if exptime is superior to 30 day, Memcached will use it as a UNIX timestamps for expiration

<bytes> : number of bytes in the data block

<cas unique> : unique 64-bit value of an existing entry (retrieved with gets command) to use with cas command

[noreply] : optional parameter that inform the server to not send the reply

These commands can return :

STORED to indicate success

NOT_STORED indicate that the data was not stored because condition for “add” or “replace” command wasn’t met, or the item is in a delete queue

EXISTS indicate that the item you are trying to store with “cas” command has been modified since last fetch

NOT_FOUND indicate that the item did not exist or has been deleted

Set

Store key/value pair in Memcached

Telnet command : set <key> <flags> <exptime> <bytes> [noreply]\r\n<value>\r\n

set key 0 900 4
data
STORED

Add

Store key/value pair in Memcached, but only if the server doesn’t already hold data for this key

Telnet command : add <key> <flags> <exptime> <bytes> [noreply]\r\n<value>\r\n

add key 0 900 2
10
STORED

Replace

Store key/value pair in Memcached, but only if the server already hold data for this key

Telnet command : replace <key> <flags> <exptime> <bytes> [noreply]\r\n<value>\r\n

replace key 0 900 2
10
STORED

Append

Add value to an existing key after existing data

Append does not take <flags> or <exptime> parameters but you must provide them !

Telnet command : append <key> <flags> <exptime> <bytes> [noreply]\r\n<value>\r\n

append key 0 900 2
10
STORED

Prepend

Add value to an existing key before existing data

Prepend does not take <flags> or <exptime> parameters but you must provide them !

Telnet command : prepend <key> <flags> <exptime> <bytes> [noreply]\r\n<value>\r\n

prepend key 0 900 2
10
STORED

Cas

Store data only if no one else has updated since the last fetch, determined with the cas tokem from gets command

Telnet command : cas <key> <flags> <exptime> <bytes> <cas unique> [noreply]\r\n

cas key 0 900 2 <cas unique>
10
STORED

 

Delete Command

Parameters :

<key> : the key to delete

[<time>] : optional time in second before real deletion of item

[noreply] : optional parameter that inform the server to not send the reply

These command can return :

DELETED to indicate success

NOT_FOUND indicate that the item did not exist or has been deleted

Delete

Store key/value pair in Memcached

Telnet command : delete <key> [<time>] [noreply]\r\n

delete key
DELETED

 

Increment/Decrement Commands

Parameters :

<key> : the key to delete

<value> : the amount to increase/decrease the item.

[noreply] : optional parameter that inform the server to not send the reply

These command can return :

NOT_FOUND indicate that the item did not exist or has been deleted

<value> increment and decrement return the result

Increment

Increment value associated with key in Memcached, item must exist, increment command will not create it

The limit of increment is the 64 bit mark

Telnet command : incr <key> <value> [noreply]\r\n

incr key 12
56

Decrement

Decrement value associated with key in Memcached, item must exist, decrement command will not create it

If you try to decrement a value bellow 0, value will stay at 0

Telnet command : decr <key> <value> [noreply]\r\n

decr key 12
44

 

Statistics Commands

Parameters :

<args> : argument to stats command

These command can return various stats that we will explain in the following

Basic stats

Return general-purpose statistics like uptime, version, memory occupation, …

Telnet command : stats\r\n

stats
STAT pid 106796
STAT uptime 5696
STAT time 1274397461
STAT version 1.4.5
STAT pointer_size 32
...
STAT total_items 344512124
STAT evictions 0
END

Items stats

Return items statistics, will display items statistics (count, age, eviction, …) organized by slabs ID

Telnet command : stats items\r\n

stats
STAT items:1:number 1125
STAT items:1:age 426
STAT items:1:evicted 0
STAT items:1:evicted_nonzero 0
STAT items:1:evicted_time 0
STAT items:1:outofmemory 0
STAT items:1:tailrepairs 0
...
STAT items:42:tailrepairs 0
END

Slabs stats

Return slabs statistics, will display slabs statistics (size, memory usage, commands count, …) organized by slabs ID

Telnet command : stats slabs\r\n

stats
STAT 1:chunk_size 80
STAT 1:chunks_per_page 13107
STAT 1:total_pages 1
STAT 1:total_chunks 13107
STAT 1:used_chunks 1125
...
STAT active_slabs 25
STAT total_malloced 10485600
END

 

Misc Commands

Flush_all

Flush the server key/value pair (invalidating them) after a optional [<time>] period

It always return OK

Telnet command : flush_all [<time>] [noreply]\r\n

flush_all 10
OK

Version

Return the Memcached server version

Telnet command : version\r\n

version
VERSION 1.4.5

Verbosity

Change the verbosity ouptut of Memcached server

It always return OK

Telnet command : verbosity <level> [noreply]\r\n

verbosity 2
OK

Quit

Server close connection when receiving this command

Telnet command : quit\r\n

quit

windows7下安装Memcached

系统:Windows7

Memcached版本:memcached 1.2.4 Win32 Beta

在执行以下命令并没有得到成功的信息:

d:\memcached>memcached -d install

failed to install service or service already installed

d:\memcached>memcached -d start

failed to start service

我只是按常理“开始”-“运行”输入:cmd,结果你懂得……

解决办法就是以管理员身份运行CMD,怎么做呢?在开始-附件-右击“命令提示符”,以管理员身份运行,重新执行安装和启动指令就可以了。

© 2017 卡片机色彩 沪ICP备13032872号-3

Theme by cipchk

to top